root/drivers/pwm/pwm-zx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_zx_pwm_chip
  2. zx_pwm_readl
  3. zx_pwm_writel
  4. zx_pwm_set_mask
  5. zx_pwm_get_state
  6. zx_pwm_config
  7. zx_pwm_apply
  8. zx_pwm_probe
  9. zx_pwm_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2017 Sanechips Technology Co., Ltd.
   4  * Copyright 2017 Linaro Ltd.
   5  */
   6 
   7 #include <linux/clk.h>
   8 #include <linux/err.h>
   9 #include <linux/io.h>
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/pwm.h>
  14 #include <linux/slab.h>
  15 
  16 #define ZX_PWM_MODE             0x0
  17 #define ZX_PWM_CLKDIV_SHIFT     2
  18 #define ZX_PWM_CLKDIV_MASK      GENMASK(11, 2)
  19 #define ZX_PWM_CLKDIV(x)        (((x) << ZX_PWM_CLKDIV_SHIFT) & \
  20                                          ZX_PWM_CLKDIV_MASK)
  21 #define ZX_PWM_POLAR            BIT(1)
  22 #define ZX_PWM_EN               BIT(0)
  23 #define ZX_PWM_PERIOD           0x4
  24 #define ZX_PWM_DUTY             0x8
  25 
  26 #define ZX_PWM_CLKDIV_MAX       1023
  27 #define ZX_PWM_PERIOD_MAX       65535
  28 
  29 struct zx_pwm_chip {
  30         struct pwm_chip chip;
  31         struct clk *pclk;
  32         struct clk *wclk;
  33         void __iomem *base;
  34 };
  35 
  36 static inline struct zx_pwm_chip *to_zx_pwm_chip(struct pwm_chip *chip)
  37 {
  38         return container_of(chip, struct zx_pwm_chip, chip);
  39 }
  40 
  41 static inline u32 zx_pwm_readl(struct zx_pwm_chip *zpc, unsigned int hwpwm,
  42                                unsigned int offset)
  43 {
  44         return readl(zpc->base + (hwpwm + 1) * 0x10 + offset);
  45 }
  46 
  47 static inline void zx_pwm_writel(struct zx_pwm_chip *zpc, unsigned int hwpwm,
  48                                  unsigned int offset, u32 value)
  49 {
  50         writel(value, zpc->base + (hwpwm + 1) * 0x10 + offset);
  51 }
  52 
  53 static void zx_pwm_set_mask(struct zx_pwm_chip *zpc, unsigned int hwpwm,
  54                             unsigned int offset, u32 mask, u32 value)
  55 {
  56         u32 data;
  57 
  58         data = zx_pwm_readl(zpc, hwpwm, offset);
  59         data &= ~mask;
  60         data |= value & mask;
  61         zx_pwm_writel(zpc, hwpwm, offset, data);
  62 }
  63 
  64 static void zx_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
  65                              struct pwm_state *state)
  66 {
  67         struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
  68         unsigned long rate;
  69         unsigned int div;
  70         u32 value;
  71         u64 tmp;
  72 
  73         value = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_MODE);
  74 
  75         if (value & ZX_PWM_POLAR)
  76                 state->polarity = PWM_POLARITY_NORMAL;
  77         else
  78                 state->polarity = PWM_POLARITY_INVERSED;
  79 
  80         if (value & ZX_PWM_EN)
  81                 state->enabled = true;
  82         else
  83                 state->enabled = false;
  84 
  85         div = (value & ZX_PWM_CLKDIV_MASK) >> ZX_PWM_CLKDIV_SHIFT;
  86         rate = clk_get_rate(zpc->wclk);
  87 
  88         tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_PERIOD);
  89         tmp *= div * NSEC_PER_SEC;
  90         state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
  91 
  92         tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_DUTY);
  93         tmp *= div * NSEC_PER_SEC;
  94         state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
  95 }
  96 
  97 static int zx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
  98                          unsigned int duty_ns, unsigned int period_ns)
  99 {
 100         struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
 101         unsigned int period_cycles, duty_cycles;
 102         unsigned long long c;
 103         unsigned int div = 1;
 104         unsigned long rate;
 105 
 106         /* Find out the best divider */
 107         rate = clk_get_rate(zpc->wclk);
 108 
 109         while (1) {
 110                 c = rate / div;
 111                 c = c * period_ns;
 112                 do_div(c, NSEC_PER_SEC);
 113 
 114                 if (c < ZX_PWM_PERIOD_MAX)
 115                         break;
 116 
 117                 div++;
 118 
 119                 if (div > ZX_PWM_CLKDIV_MAX)
 120                         return -ERANGE;
 121         }
 122 
 123         /* Calculate duty cycles */
 124         period_cycles = c;
 125         c *= duty_ns;
 126         do_div(c, period_ns);
 127         duty_cycles = c;
 128 
 129         /*
 130          * If the PWM is being enabled, we have to temporarily disable it
 131          * before configuring the registers.
 132          */
 133         if (pwm_is_enabled(pwm))
 134                 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_EN, 0);
 135 
 136         /* Set up registers */
 137         zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_CLKDIV_MASK,
 138                         ZX_PWM_CLKDIV(div));
 139         zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_PERIOD, period_cycles);
 140         zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_DUTY, duty_cycles);
 141 
 142         /* Re-enable the PWM if needed */
 143         if (pwm_is_enabled(pwm))
 144                 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
 145                                 ZX_PWM_EN, ZX_PWM_EN);
 146 
 147         return 0;
 148 }
 149 
 150 static int zx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 151                         const struct pwm_state *state)
 152 {
 153         struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
 154         struct pwm_state cstate;
 155         int ret;
 156 
 157         pwm_get_state(pwm, &cstate);
 158 
 159         if (state->polarity != cstate.polarity)
 160                 zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_POLAR,
 161                                 (state->polarity == PWM_POLARITY_INVERSED) ?
 162                                  0 : ZX_PWM_POLAR);
 163 
 164         if (state->period != cstate.period ||
 165             state->duty_cycle != cstate.duty_cycle) {
 166                 ret = zx_pwm_config(chip, pwm, state->duty_cycle,
 167                                     state->period);
 168                 if (ret)
 169                         return ret;
 170         }
 171 
 172         if (state->enabled != cstate.enabled) {
 173                 if (state->enabled) {
 174                         ret = clk_prepare_enable(zpc->wclk);
 175                         if (ret)
 176                                 return ret;
 177 
 178                         zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
 179                                         ZX_PWM_EN, ZX_PWM_EN);
 180                 } else {
 181                         zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
 182                                         ZX_PWM_EN, 0);
 183                         clk_disable_unprepare(zpc->wclk);
 184                 }
 185         }
 186 
 187         return 0;
 188 }
 189 
 190 static const struct pwm_ops zx_pwm_ops = {
 191         .apply = zx_pwm_apply,
 192         .get_state = zx_pwm_get_state,
 193         .owner = THIS_MODULE,
 194 };
 195 
 196 static int zx_pwm_probe(struct platform_device *pdev)
 197 {
 198         struct zx_pwm_chip *zpc;
 199         struct resource *res;
 200         unsigned int i;
 201         int ret;
 202 
 203         zpc = devm_kzalloc(&pdev->dev, sizeof(*zpc), GFP_KERNEL);
 204         if (!zpc)
 205                 return -ENOMEM;
 206 
 207         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 208         zpc->base = devm_ioremap_resource(&pdev->dev, res);
 209         if (IS_ERR(zpc->base))
 210                 return PTR_ERR(zpc->base);
 211 
 212         zpc->pclk = devm_clk_get(&pdev->dev, "pclk");
 213         if (IS_ERR(zpc->pclk))
 214                 return PTR_ERR(zpc->pclk);
 215 
 216         zpc->wclk = devm_clk_get(&pdev->dev, "wclk");
 217         if (IS_ERR(zpc->wclk))
 218                 return PTR_ERR(zpc->wclk);
 219 
 220         ret = clk_prepare_enable(zpc->pclk);
 221         if (ret)
 222                 return ret;
 223 
 224         zpc->chip.dev = &pdev->dev;
 225         zpc->chip.ops = &zx_pwm_ops;
 226         zpc->chip.base = -1;
 227         zpc->chip.npwm = 4;
 228         zpc->chip.of_xlate = of_pwm_xlate_with_flags;
 229         zpc->chip.of_pwm_n_cells = 3;
 230 
 231         /*
 232          * PWM devices may be enabled by firmware, and let's disable all of
 233          * them initially to save power.
 234          */
 235         for (i = 0; i < zpc->chip.npwm; i++)
 236                 zx_pwm_set_mask(zpc, i, ZX_PWM_MODE, ZX_PWM_EN, 0);
 237 
 238         ret = pwmchip_add(&zpc->chip);
 239         if (ret < 0) {
 240                 dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
 241                 return ret;
 242         }
 243 
 244         platform_set_drvdata(pdev, zpc);
 245 
 246         return 0;
 247 }
 248 
 249 static int zx_pwm_remove(struct platform_device *pdev)
 250 {
 251         struct zx_pwm_chip *zpc = platform_get_drvdata(pdev);
 252         int ret;
 253 
 254         ret = pwmchip_remove(&zpc->chip);
 255         clk_disable_unprepare(zpc->pclk);
 256 
 257         return ret;
 258 }
 259 
 260 static const struct of_device_id zx_pwm_dt_ids[] = {
 261         { .compatible = "zte,zx296718-pwm", },
 262         { /* sentinel */ }
 263 };
 264 MODULE_DEVICE_TABLE(of, zx_pwm_dt_ids);
 265 
 266 static struct platform_driver zx_pwm_driver = {
 267         .driver = {
 268                 .name = "zx-pwm",
 269                 .of_match_table = zx_pwm_dt_ids,
 270         },
 271         .probe = zx_pwm_probe,
 272         .remove = zx_pwm_remove,
 273 };
 274 module_platform_driver(zx_pwm_driver);
 275 
 276 MODULE_ALIAS("platform:zx-pwm");
 277 MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
 278 MODULE_DESCRIPTION("ZTE ZX PWM Driver");
 279 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */