summaryrefslogtreecommitdiff
path: root/drivers/pwm/pwm-imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-imx.c')
-rw-r--r--drivers/pwm/pwm-imx.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 05d90af194cb..0b8da21a0b1d 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -47,6 +47,8 @@
#define MX3_PWM_SWR_LOOP 5
+#define MX3_PWMCR_OUTPIN_DISCONNECT (3 << 18)
+
struct imx_chip {
struct clk *clk_per;
struct clk *clk_ipg;
@@ -58,6 +60,7 @@ struct imx_chip {
int (*config)(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns);
void (*set_enable)(struct pwm_chip *chip, bool enable);
+ void (*out_enable)(struct pwm_chip *chip, bool enable);
};
#define to_imx_chip(chip) container_of(chip, struct imx_chip, chip)
@@ -106,6 +109,21 @@ static void imx_pwm_set_enable_v1(struct pwm_chip *chip, bool enable)
writel(val, imx->mmio_base + MX1_PWMC);
}
+static void imx_pwm_out_enable_v1(struct pwm_chip *chip, bool enable)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ u32 val;
+
+ val = readl(imx->mmio_base + MX1_PWMC);
+
+ if (enable)
+ val |= MX1_PWMC_EN;
+ else
+ val &= ~MX1_PWMC_EN;
+
+ writel(val, imx->mmio_base + MX1_PWMC);
+}
+
static int imx_pwm_config_v2(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns)
{
@@ -199,6 +217,21 @@ static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable)
writel(val, imx->mmio_base + MX3_PWMCR);
}
+static void imx_pwm_out_enable_v2(struct pwm_chip *chip, bool enable)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+ u32 val;
+
+ val = readl(imx->mmio_base + MX3_PWMCR);
+
+ if (enable)
+ val &= ~(MX3_PWMCR_OUTPIN_DISCONNECT);
+ else
+ val |= (MX3_PWMCR_OUTPIN_DISCONNECT);
+
+ writel(val, imx->mmio_base + MX3_PWMCR);
+}
+
static int imx_pwm_config(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns)
{
@@ -239,10 +272,18 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
clk_disable_unprepare(imx->clk_per);
}
+static void imx_pwm_out_enable(struct pwm_chip *chip, bool enable)
+{
+ struct imx_chip *imx = to_imx_chip(chip);
+
+ imx->out_enable(chip, enable);
+}
+
static struct pwm_ops imx_pwm_ops = {
.enable = imx_pwm_enable,
.disable = imx_pwm_disable,
.config = imx_pwm_config,
+ .out_enable = imx_pwm_out_enable,
.owner = THIS_MODULE,
};
@@ -250,16 +291,19 @@ struct imx_pwm_data {
int (*config)(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns);
void (*set_enable)(struct pwm_chip *chip, bool enable);
+ void (*out_enable)(struct pwm_chip *chip, bool enable);
};
static struct imx_pwm_data imx_pwm_data_v1 = {
.config = imx_pwm_config_v1,
.set_enable = imx_pwm_set_enable_v1,
+ .out_enable = imx_pwm_out_enable_v1,
};
static struct imx_pwm_data imx_pwm_data_v2 = {
.config = imx_pwm_config_v2,
.set_enable = imx_pwm_set_enable_v2,
+ .out_enable = imx_pwm_out_enable_v2,
};
static const struct of_device_id imx_pwm_dt_ids[] = {
@@ -314,6 +358,7 @@ static int imx_pwm_probe(struct platform_device *pdev)
data = of_id->data;
imx->config = data->config;
imx->set_enable = data->set_enable;
+ imx->out_enable = data->out_enable;
ret = pwmchip_add(&imx->chip);
if (ret < 0)