aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pwm/Kconfig17
-rw-r--r--drivers/pwm/Makefile3
-rw-r--r--drivers/pwm/core.c10
-rw-r--r--drivers/pwm/pwm-imx1.c199
-rw-r--r--drivers/pwm/pwm-imx27.c (renamed from drivers/pwm/pwm-imx.c)217
-rw-r--r--include/linux/pwm.h37
6 files changed, 293 insertions, 190 deletions
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index a8f47df0655a..54f8238aac0d 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -192,14 +192,23 @@ config PWM_IMG
To compile this driver as a module, choose M here: the module
will be called pwm-img
-config PWM_IMX
- tristate "i.MX PWM support"
+config PWM_IMX1
+ tristate "i.MX1 PWM support"
depends on ARCH_MXC
help
- Generic PWM framework driver for i.MX.
+ Generic PWM framework driver for i.MX1 and i.MX21
To compile this driver as a module, choose M here: the module
- will be called pwm-imx.
+ will be called pwm-imx1.
+
+config PWM_IMX27
+ tristate "i.MX27 PWM support"
+ depends on ARCH_MXC
+ help
+ Generic PWM framework driver for i.MX27 and later i.MX SoCs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-imx27.
config PWM_JZ4740
tristate "Ingenic JZ47xx PWM support"
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 9c676a0dadf5..448825e892bc 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -17,7 +17,8 @@ obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
obj-$(CONFIG_PWM_HIBVT) += pwm-hibvt.o
obj-$(CONFIG_PWM_IMG) += pwm-img.o
-obj-$(CONFIG_PWM_IMX) += pwm-imx.o
+obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o
+obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
obj-$(CONFIG_PWM_LPC18XX_SCT) += pwm-lpc18xx-sct.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 1581f6ab1b1f..3149204567f3 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -472,7 +472,10 @@ int pwm_apply_state(struct pwm_device *pwm, struct pwm_state *state)
state->duty_cycle > state->period)
return -EINVAL;
- if (!memcmp(state, &pwm->state, sizeof(*state)))
+ if (state->period == pwm->state.period &&
+ state->duty_cycle == pwm->state.duty_cycle &&
+ state->polarity == pwm->state.polarity &&
+ state->enabled == pwm->state.enabled)
return 0;
if (pwm->chip->ops->apply) {
@@ -1033,10 +1036,7 @@ static int pwm_seq_show(struct seq_file *s, void *v)
dev_name(chip->dev), chip->npwm,
(chip->npwm != 1) ? "s" : "");
- if (chip->ops->dbg_show)
- chip->ops->dbg_show(chip, s);
- else
- pwm_dbg_show(chip, s);
+ pwm_dbg_show(chip, s);
return 0;
}
diff --git a/drivers/pwm/pwm-imx1.c b/drivers/pwm/pwm-imx1.c
new file mode 100644
index 000000000000..f8b2c2e001a7
--- /dev/null
+++ b/drivers/pwm/pwm-imx1.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * simple driver for PWM (Pulse Width Modulator) controller
+ *
+ * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define MX1_PWMC 0x00 /* PWM Control Register */
+#define MX1_PWMS 0x04 /* PWM Sample Register */
+#define MX1_PWMP 0x08 /* PWM Period Register */
+
+#define MX1_PWMC_EN BIT(4)
+
+struct pwm_imx1_chip {
+ struct clk *clk_ipg;
+ struct clk *clk_per;
+ void __iomem *mmio_base;
+ struct pwm_chip chip;
+};
+
+#define to_pwm_imx1_chip(chip) container_of(chip, struct pwm_imx1_chip, chip)
+
+static int pwm_imx1_clk_prepare_enable(struct pwm_chip *chip)
+{
+ struct pwm_imx1_chip *imx = to_pwm_imx1_chip(chip);
+ int ret;
+
+ ret = clk_prepare_enable(imx->clk_ipg);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(imx->clk_per);
+ if (ret) {
+ clk_disable_unprepare(imx->clk_ipg);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void pwm_imx1_clk_disable_unprepare(struct pwm_chip *chip)
+{
+ struct pwm_imx1_chip *imx = to_pwm_imx1_chip(chip);
+
+ clk_disable_unprepare(imx->clk_per);
+ clk_disable_unprepare(imx->clk_ipg);
+}
+
+static int pwm_imx1_config(struct pwm_chip *chip,
+ struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ struct pwm_imx1_chip *imx = to_pwm_imx1_chip(chip);
+ u32 max, p;
+
+ /*
+ * The PWM subsystem allows for exact frequencies. However,
+ * I cannot connect a scope on my device to the PWM line and
+ * thus cannot provide the program the PWM controller
+ * exactly. Instead, I'm relying on the fact that the
+ * Bootloader (u-boot or WinCE+haret) has programmed the PWM
+ * function group already. So I'll just modify the PWM sample
+ * register to follow the ratio of duty_ns vs. period_ns
+ * accordingly.
+ *
+ * This is good enough for programming the brightness of
+ * the LCD backlight.
+ *
+ * The real implementation would divide PERCLK[0] first by
+ * both the prescaler (/1 .. /128) and then by CLKSEL
+ * (/2 .. /16).
+ */
+ max = readl(imx->mmio_base + MX1_PWMP);
+ p = max * duty_ns / period_ns;
+
+ writel(max - p, imx->mmio_base + MX1_PWMS);
+
+ return 0;
+}
+
+static int pwm_imx1_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct pwm_imx1_chip *imx = to_pwm_imx1_chip(chip);
+ u32 value;
+ int ret;
+
+ ret = pwm_imx1_clk_prepare_enable(chip);
+ if (ret < 0)
+ return ret;
+
+ value = readl(imx->mmio_base + MX1_PWMC);
+ value |= MX1_PWMC_EN;
+ writel(value, imx->mmio_base + MX1_PWMC);
+
+ return 0;
+}
+
+static void pwm_imx1_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+ struct pwm_imx1_chip *imx = to_pwm_imx1_chip(chip);
+ u32 value;
+
+ value = readl(imx->mmio_base + MX1_PWMC);
+ value &= ~MX1_PWMC_EN;
+ writel(value, imx->mmio_base + MX1_PWMC);
+
+ pwm_imx1_clk_disable_unprepare(chip);
+}
+
+static const struct pwm_ops pwm_imx1_ops = {
+ .enable = pwm_imx1_enable,
+ .disable = pwm_imx1_disable,
+ .config = pwm_imx1_config,
+ .owner = THIS_MODULE,
+};
+
+static const struct of_device_id pwm_imx1_dt_ids[] = {
+ { .compatible = "fsl,imx1-pwm", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pwm_imx1_dt_ids);
+
+static int pwm_imx1_probe(struct platform_device *pdev)
+{
+ struct pwm_imx1_chip *imx;
+ struct resource *r;
+
+ imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
+ if (!imx)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, imx);
+
+ imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(imx->clk_ipg)) {
+ dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
+ PTR_ERR(imx->clk_ipg));
+ return PTR_ERR(imx->clk_ipg);
+ }
+
+ imx->clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(imx->clk_per)) {
+ int ret = PTR_ERR(imx->clk_per);
+
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to get peripheral clock: %d\n",
+ ret);
+
+ return ret;
+ }
+
+ imx->chip.ops = &pwm_imx1_ops;
+ imx->chip.dev = &pdev->dev;
+ imx->chip.base = -1;
+ imx->chip.npwm = 1;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ imx->mmio_base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(imx->mmio_base))
+ return PTR_ERR(imx->mmio_base);
+
+ return pwmchip_add(&imx->chip);
+}
+
+static int pwm_imx1_remove(struct platform_device *pdev)
+{
+ struct pwm_imx1_chip *imx = platform_get_drvdata(pdev);
+
+ pwm_imx1_clk_disable_unprepare(&imx->chip);
+
+ return pwmchip_remove(&imx->chip);
+}
+
+static struct platform_driver pwm_imx1_driver = {
+ .driver = {
+ .name = "pwm-imx1",
+ .of_match_table = pwm_imx1_dt_ids,
+ },
+ .probe = pwm_imx1_probe,
+ .remove = pwm_imx1_remove,
+};
+module_platform_driver(pwm_imx1_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx27.c
index 55a3a363d5be..55666cca4cee 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx27.c
@@ -19,16 +19,6 @@
#include <linux/pwm.h>
#include <linux/slab.h>
-/* i.MX1 and i.MX21 share the same PWM function block: */
-
-#define MX1_PWMC 0x00 /* PWM Control Register */
-#define MX1_PWMS 0x04 /* PWM Sample Register */
-#define MX1_PWMP 0x08 /* PWM Period Register */
-
-#define MX1_PWMC_EN BIT(4)
-
-/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
-
#define MX3_PWMCR 0x00 /* PWM Control Register */
#define MX3_PWMSR 0x04 /* PWM Status Register */
#define MX3_PWMSAR 0x0C /* PWM Sample Register */
@@ -86,21 +76,18 @@
/* PWMPR register value of 0xffff has the same effect as 0xfffe */
#define MX3_PWMPR_MAX 0xfffe
-struct imx_chip {
+struct pwm_imx27_chip {
struct clk *clk_ipg;
-
struct clk *clk_per;
-
void __iomem *mmio_base;
-
struct pwm_chip chip;
};
-#define to_imx_chip(chip) container_of(chip, struct imx_chip, chip)
+#define to_pwm_imx27_chip(chip) container_of(chip, struct pwm_imx27_chip, chip)
-static int imx_pwm_clk_prepare_enable(struct pwm_chip *chip)
+static int pwm_imx27_clk_prepare_enable(struct pwm_chip *chip)
{
- struct imx_chip *imx = to_imx_chip(chip);
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
int ret;
ret = clk_prepare_enable(imx->clk_ipg);
@@ -116,22 +103,23 @@ static int imx_pwm_clk_prepare_enable(struct pwm_chip *chip)
return 0;
}
-static void imx_pwm_clk_disable_unprepare(struct pwm_chip *chip)
+static void pwm_imx27_clk_disable_unprepare(struct pwm_chip *chip)
{
- struct imx_chip *imx = to_imx_chip(chip);
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
clk_disable_unprepare(imx->clk_per);
clk_disable_unprepare(imx->clk_ipg);
}
-static void imx_pwm_get_state(struct pwm_chip *chip,
- struct pwm_device *pwm, struct pwm_state *state)
+static void pwm_imx27_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm, struct pwm_state *state)
{
- struct imx_chip *imx = to_imx_chip(chip);
- u32 period, prescaler, pwm_clk, ret, val;
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
+ u32 period, prescaler, pwm_clk, val;
u64 tmp;
+ int ret;
- ret = imx_pwm_clk_prepare_enable(chip);
+ ret = pwm_imx27_clk_prepare_enable(chip);
if (ret < 0)
return;
@@ -139,7 +127,7 @@ static void imx_pwm_get_state(struct pwm_chip *chip,
if (val & MX3_PWMCR_EN) {
state->enabled = true;
- ret = imx_pwm_clk_prepare_enable(chip);
+ ret = pwm_imx27_clk_prepare_enable(chip);
if (ret)
return;
} else {
@@ -176,70 +164,12 @@ static void imx_pwm_get_state(struct pwm_chip *chip,
state->duty_cycle = 0;
}
- imx_pwm_clk_disable_unprepare(chip);
-}
-
-static int imx_pwm_config_v1(struct pwm_chip *chip,
- struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- struct imx_chip *imx = to_imx_chip(chip);
-
- /*
- * The PWM subsystem allows for exact frequencies. However,
- * I cannot connect a scope on my device to the PWM line and
- * thus cannot provide the program the PWM controller
- * exactly. Instead, I'm relying on the fact that the
- * Bootloader (u-boot or WinCE+haret) has programmed the PWM
- * function group already. So I'll just modify the PWM sample
- * register to follow the ratio of duty_ns vs. period_ns
- * accordingly.
- *
- * This is good enough for programming the brightness of
- * the LCD backlight.
- *
- * The real implementation would divide PERCLK[0] first by
- * both the prescaler (/1 .. /128) and then by CLKSEL
- * (/2 .. /16).
- */
- u32 max = readl(imx->mmio_base + MX1_PWMP);
- u32 p = max * duty_ns / period_ns;
- writel(max - p, imx->mmio_base + MX1_PWMS);
-
- return 0;
-}
-
-static int imx_pwm_enable_v1(struct pwm_chip *chip, struct pwm_device *pwm)
-{
- struct imx_chip *imx = to_imx_chip(chip);
- u32 val;
- int ret;
-
- ret = imx_pwm_clk_prepare_enable(chip);
- if (ret < 0)
- return ret;
-
- val = readl(imx->mmio_base + MX1_PWMC);
- val |= MX1_PWMC_EN;
- writel(val, imx->mmio_base + MX1_PWMC);
-
- return 0;
-}
-
-static void imx_pwm_disable_v1(struct pwm_chip *chip, struct pwm_device *pwm)
-{
- struct imx_chip *imx = to_imx_chip(chip);
- u32 val;
-
- val = readl(imx->mmio_base + MX1_PWMC);
- val &= ~MX1_PWMC_EN;
- writel(val, imx->mmio_base + MX1_PWMC);
-
- imx_pwm_clk_disable_unprepare(chip);
+ pwm_imx27_clk_disable_unprepare(chip);
}
-static void imx_pwm_sw_reset(struct pwm_chip *chip)
+static void pwm_imx27_sw_reset(struct pwm_chip *chip)
{
- struct imx_chip *imx = to_imx_chip(chip);
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
struct device *dev = chip->dev;
int wait_count = 0;
u32 cr;
@@ -255,10 +185,10 @@ static void imx_pwm_sw_reset(struct pwm_chip *chip)
dev_warn(dev, "software reset timeout\n");
}
-static void imx_pwm_wait_fifo_slot(struct pwm_chip *chip,
- struct pwm_device *pwm)
+static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
+ struct pwm_device *pwm)
{
- struct imx_chip *imx = to_imx_chip(chip);
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
struct device *dev = chip->dev;
unsigned int period_ms;
int fifoav;
@@ -277,11 +207,11 @@ static void imx_pwm_wait_fifo_slot(struct pwm_chip *chip,
}
}
-static int imx_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
{
unsigned long period_cycles, duty_cycles, prescale;
- struct imx_chip *imx = to_imx_chip(chip);
+ struct pwm_imx27_chip *imx = to_pwm_imx27_chip(chip);
struct pwm_state cstate;
unsigned long long c;
int ret;
@@ -318,13 +248,13 @@ static int imx_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
* enabled.
*/
if (cstate.enabled) {
- imx_pwm_wait_fifo_slot(chip, pwm);
+ pwm_imx27_wait_fifo_slot(chip, pwm);
} else {
- ret = imx_pwm_clk_prepare_enable(chip);
+ ret = pwm_imx27_clk_prepare_enable(chip);
if (ret)
return ret;
- imx_pwm_sw_reset(chip);
+ pwm_imx27_sw_reset(chip);
}
writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
@@ -343,64 +273,35 @@ static int imx_pwm_apply_v2(struct pwm_chip *chip, struct pwm_device *pwm,
} else if (cstate.enabled) {
writel(0, imx->mmio_base + MX3_PWMCR);
- imx_pwm_clk_disable_unprepare(chip);
+ pwm_imx27_clk_disable_unprepare(chip);
}
return 0;
}
-static const struct pwm_ops imx_pwm_ops_v1 = {
- .enable = imx_pwm_enable_v1,
- .disable = imx_pwm_disable_v1,
- .config = imx_pwm_config_v1,
+static const struct pwm_ops pwm_imx27_ops = {
+ .apply = pwm_imx27_apply,
+ .get_state = pwm_imx27_get_state,
.owner = THIS_MODULE,
};
-static const struct pwm_ops imx_pwm_ops_v2 = {
- .apply = imx_pwm_apply_v2,
- .get_state = imx_pwm_get_state,
- .owner = THIS_MODULE,
-};
-
-struct imx_pwm_data {
- bool polarity_supported;
- const struct pwm_ops *ops;
-};
-
-static struct imx_pwm_data imx_pwm_data_v1 = {
- .ops = &imx_pwm_ops_v1,
-};
-
-static struct imx_pwm_data imx_pwm_data_v2 = {
- .polarity_supported = true,
- .ops = &imx_pwm_ops_v2,
-};
-
-static const struct of_device_id imx_pwm_dt_ids[] = {
- { .compatible = "fsl,imx1-pwm", .data = &imx_pwm_data_v1, },
- { .compatible = "fsl,imx27-pwm", .data = &imx_pwm_data_v2, },
+static const struct of_device_id pwm_imx27_dt_ids[] = {
+ { .compatible = "fsl,imx27-pwm", },
{ /* sentinel */ }
};
-MODULE_DEVICE_TABLE(of, imx_pwm_dt_ids);
+MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids);
-static int imx_pwm_probe(struct platform_device *pdev)
+static int pwm_imx27_probe(struct platform_device *pdev)
{
- const struct of_device_id *of_id =
- of_match_device(imx_pwm_dt_ids, &pdev->dev);
- const struct imx_pwm_data *data;
- struct imx_chip *imx;
+ struct pwm_imx27_chip *imx;
struct resource *r;
- int ret = 0;
-
- if (!of_id)
- return -ENODEV;
-
- data = of_id->data;
imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
if (imx == NULL)
return -ENOMEM;
+ platform_set_drvdata(pdev, imx);
+
imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(imx->clk_ipg)) {
dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
@@ -410,57 +311,51 @@ static int imx_pwm_probe(struct platform_device *pdev)
imx->clk_per = devm_clk_get(&pdev->dev, "per");
if (IS_ERR(imx->clk_per)) {
- dev_err(&pdev->dev, "getting per clock failed with %ld\n",
- PTR_ERR(imx->clk_per));
- return PTR_ERR(imx->clk_per);
+ int ret = PTR_ERR(imx->clk_per);
+
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to get peripheral clock: %d\n",
+ ret);
+
+ return ret;
}
- imx->chip.ops = data->ops;
+ imx->chip.ops = &pwm_imx27_ops;
imx->chip.dev = &pdev->dev;
imx->chip.base = -1;
imx->chip.npwm = 1;
- if (data->polarity_supported) {
- dev_dbg(&pdev->dev, "PWM supports output inversion\n");
- imx->chip.of_xlate = of_pwm_xlate_with_flags;
- imx->chip.of_pwm_n_cells = 3;
- }
+ imx->chip.of_xlate = of_pwm_xlate_with_flags;
+ imx->chip.of_pwm_n_cells = 3;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
imx->mmio_base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(imx->mmio_base))
return PTR_ERR(imx->mmio_base);
- ret = pwmchip_add(&imx->chip);
- if (ret < 0)
- return ret;
-
- platform_set_drvdata(pdev, imx);
- return 0;
+ return pwmchip_add(&imx->chip);
}
-static int imx_pwm_remove(struct platform_device *pdev)
+static int pwm_imx27_remove(struct platform_device *pdev)
{
- struct imx_chip *imx;
+ struct pwm_imx27_chip *imx;
imx = platform_get_drvdata(pdev);
- if (imx == NULL)
- return -ENODEV;
- imx_pwm_clk_disable_unprepare(&imx->chip);
+ pwm_imx27_clk_disable_unprepare(&imx->chip);
return pwmchip_remove(&imx->chip);
}
static struct platform_driver imx_pwm_driver = {
- .driver = {
- .name = "imx-pwm",
- .of_match_table = imx_pwm_dt_ids,
+ .driver = {
+ .name = "pwm-imx27",
+ .of_match_table = pwm_imx27_dt_ids,
},
- .probe = imx_pwm_probe,
- .remove = imx_pwm_remove,
+ .probe = pwm_imx27_probe,
+ .remove = pwm_imx27_remove,
};
-
module_platform_driver(imx_pwm_driver);
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index d5199b507d79..b628abfffacc 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -242,11 +242,7 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle,
* struct pwm_ops - PWM controller operations
* @request: optional hook for requesting a PWM
* @free: optional hook for freeing a PWM
- * @config: configure duty cycles and period length for this PWM
- * @set_polarity: configure the polarity of this PWM
* @capture: capture and report PWM signal
- * @enable: enable PWM output toggling
- * @disable: disable PWM output toggling
* @apply: atomically apply a new PWM config. The state argument
* should be adjusted with the real hardware config (if the
* approximate the period or duty_cycle value, state should
@@ -254,53 +250,56 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle,
* @get_state: get the current PWM state. This function is only
* called once per PWM device when the PWM chip is
* registered.
- * @dbg_show: optional routine to show contents in debugfs
* @owner: helps prevent removal of modules exporting active PWMs
+ * @config: configure duty cycles and period length for this PWM
+ * @set_polarity: configure the polarity of this PWM
+ * @enable: enable PWM output toggling
+ * @disable: disable PWM output toggling
*/
struct pwm_ops {
int (*request)(struct pwm_chip *chip, struct pwm_device *pwm);
void (*free)(struct pwm_chip *chip, struct pwm_device *pwm);
- int (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
- int duty_ns, int period_ns);
- int (*set_polarity)(struct pwm_chip *chip, struct pwm_device *pwm,
- enum pwm_polarity polarity);
int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_capture *result, unsigned long timeout);
- int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
- void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state);
void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state);
-#ifdef CONFIG_DEBUG_FS
- void (*dbg_show)(struct pwm_chip *chip, struct seq_file *s);
-#endif
struct module *owner;
+
+ /* Only used by legacy drivers */
+ int (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
+ int duty_ns, int period_ns);
+ int (*set_polarity)(struct pwm_chip *chip, struct pwm_device *pwm,
+ enum pwm_polarity polarity);
+ int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm);
+ void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm);
};
/**
* struct pwm_chip - abstract a PWM controller
* @dev: device providing the PWMs
- * @list: list node for internal use
* @ops: callbacks for this PWM controller
* @base: number of first PWM controlled by this chip
* @npwm: number of PWMs controlled by this chip
- * @pwms: array of PWM devices allocated by the framework
* @of_xlate: request a PWM device given a device tree PWM specifier
* @of_pwm_n_cells: number of cells expected in the device tree PWM specifier
+ * @list: list node for internal use
+ * @pwms: array of PWM devices allocated by the framework
*/
struct pwm_chip {
struct device *dev;
- struct list_head list;
const struct pwm_ops *ops;
int base;
unsigned int npwm;
- struct pwm_device *pwms;
-
struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
const struct of_phandle_args *args);
unsigned int of_pwm_n_cells;
+
+ /* only used internally by the PWM framework */
+ struct list_head list;
+ struct pwm_device *pwms;
};
/**