^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * NXP LPC18xx State Configurable Timer - Pulse Width Modulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2015 Ariel D'Alessandro <ariel@vanguardiasur.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Notes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * =====
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * NXP LPC18xx provides a State Configurable Timer (SCT) which can be configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * as a Pulse Width Modulator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * SCT supports 16 outputs, 16 events and 16 registers. Each event will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * triggered when its related register matches the SCT counter value, and it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * will set or clear a selected output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * One of the events is preselected to generate the period, thus the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * number of simultaneous channels is limited to 15. Notice that period is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * global to all the channels, thus PWM driver will refuse setting different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * values to it, unless there's only one channel requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/pwm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* LPC18xx SCT registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define LPC18XX_PWM_CONFIG 0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define LPC18XX_PWM_CONFIG_UNIFY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define LPC18XX_PWM_CONFIG_NORELOAD BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define LPC18XX_PWM_CTRL 0x004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define LPC18XX_PWM_CTRL_HALT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define LPC18XX_PWM_BIDIR BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define LPC18XX_PWM_PRE_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define LPC18XX_PWM_PRE_MASK (0xff << LPC18XX_PWM_PRE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define LPC18XX_PWM_PRE(x) (x << LPC18XX_PWM_PRE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define LPC18XX_PWM_LIMIT 0x008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define LPC18XX_PWM_RES_BASE 0x058
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define LPC18XX_PWM_RES_SHIFT(_ch) (_ch * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define LPC18XX_PWM_RES(_ch, _action) (_action << LPC18XX_PWM_RES_SHIFT(_ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define LPC18XX_PWM_RES_MASK(_ch) (0x3 << LPC18XX_PWM_RES_SHIFT(_ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define LPC18XX_PWM_MATCH_BASE 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define LPC18XX_PWM_MATCH(_ch) (LPC18XX_PWM_MATCH_BASE + _ch * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define LPC18XX_PWM_MATCHREL_BASE 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define LPC18XX_PWM_MATCHREL(_ch) (LPC18XX_PWM_MATCHREL_BASE + _ch * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define LPC18XX_PWM_EVSTATEMSK_BASE 0x300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define LPC18XX_PWM_EVSTATEMSK(_ch) (LPC18XX_PWM_EVSTATEMSK_BASE + _ch * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define LPC18XX_PWM_EVSTATEMSK_ALL 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define LPC18XX_PWM_EVCTRL_BASE 0x304
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define LPC18XX_PWM_EVCTRL(_ev) (LPC18XX_PWM_EVCTRL_BASE + _ev * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define LPC18XX_PWM_EVCTRL_MATCH(_ch) _ch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define LPC18XX_PWM_EVCTRL_COMB_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define LPC18XX_PWM_EVCTRL_COMB_MATCH (0x1 << LPC18XX_PWM_EVCTRL_COMB_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define LPC18XX_PWM_OUTPUTSET_BASE 0x500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define LPC18XX_PWM_OUTPUTSET(_ch) (LPC18XX_PWM_OUTPUTSET_BASE + _ch * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define LPC18XX_PWM_OUTPUTCL_BASE 0x504
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define LPC18XX_PWM_OUTPUTCL(_ch) (LPC18XX_PWM_OUTPUTCL_BASE + _ch * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* LPC18xx SCT unified counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define LPC18XX_PWM_TIMER_MAX 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* LPC18xx SCT events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define LPC18XX_PWM_EVENT_PERIOD 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LPC18XX_PWM_EVENT_MAX 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* SCT conflict resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) enum lpc18xx_pwm_res_action {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) LPC18XX_PWM_RES_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) LPC18XX_PWM_RES_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) LPC18XX_PWM_RES_CLEAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) LPC18XX_PWM_RES_TOGGLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct lpc18xx_pwm_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int duty_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct lpc18xx_pwm_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct pwm_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct clk *pwm_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned long clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned int period_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned int min_period_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int max_period_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned int period_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long event_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct mutex res_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct mutex period_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static inline struct lpc18xx_pwm_chip *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) to_lpc18xx_pwm_chip(struct pwm_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return container_of(chip, struct lpc18xx_pwm_chip, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static inline void lpc18xx_pwm_writel(struct lpc18xx_pwm_chip *lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) writel(val, lpc18xx_pwm->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline u32 lpc18xx_pwm_readl(struct lpc18xx_pwm_chip *lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return readl(lpc18xx_pwm->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void lpc18xx_pwm_set_conflict_res(struct lpc18xx_pwm_chip *lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum lpc18xx_pwm_res_action action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mutex_lock(&lpc18xx_pwm->res_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Simultaneous set and clear may happen on an output, that is the case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * when duty_ns == period_ns. LPC18xx SCT allows to set a conflict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * resolution action to be taken in such a case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_RES_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) val &= ~LPC18XX_PWM_RES_MASK(pwm->hwpwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) val |= LPC18XX_PWM_RES(pwm->hwpwm, action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_RES_BASE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mutex_unlock(&lpc18xx_pwm->res_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static void lpc18xx_pwm_config_period(struct pwm_chip *chip, int period_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) val = (u64)period_ns * lpc18xx_pwm->clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) do_div(val, NSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) LPC18XX_PWM_MATCH(lpc18xx_pwm->period_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) (u32)val - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) LPC18XX_PWM_MATCHREL(lpc18xx_pwm->period_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) (u32)val - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct pwm_device *pwm, int duty_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) val = (u64)duty_ns * lpc18xx_pwm->clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) do_div(val, NSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) LPC18XX_PWM_MATCH(lpc18xx_data->duty_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) (u32)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) LPC18XX_PWM_MATCHREL(lpc18xx_data->duty_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) (u32)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int duty_ns, int period_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int requested_events, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (period_ns < lpc18xx_pwm->min_period_ns ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) period_ns > lpc18xx_pwm->max_period_ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev_err(chip->dev, "period %d not in range\n", period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mutex_lock(&lpc18xx_pwm->period_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) requested_events = bitmap_weight(&lpc18xx_pwm->event_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) LPC18XX_PWM_EVENT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * The PWM supports only a single period for all PWM channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Once the period is set, it can only be changed if no more than one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * channel is requested at that moment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (requested_events > 2 && lpc18xx_pwm->period_ns != period_ns &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) lpc18xx_pwm->period_ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dev_err(chip->dev, "conflicting period requested for PWM %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pwm->hwpwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) mutex_unlock(&lpc18xx_pwm->period_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if ((requested_events <= 2 && lpc18xx_pwm->period_ns != period_ns) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) !lpc18xx_pwm->period_ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) lpc18xx_pwm->period_ns = period_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) for (i = 0; i < chip->npwm; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) pwm_set_period(&chip->pwms[i], period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) lpc18xx_pwm_config_period(chip, period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mutex_unlock(&lpc18xx_pwm->period_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) lpc18xx_pwm_config_duty(chip, pwm, duty_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int lpc18xx_pwm_set_polarity(struct pwm_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) enum pwm_polarity polarity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int lpc18xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) enum lpc18xx_pwm_res_action res_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned int set_event, clear_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) LPC18XX_PWM_EVCTRL_MATCH(lpc18xx_data->duty_event) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) LPC18XX_PWM_EVCTRL_COMB_MATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) LPC18XX_PWM_EVSTATEMSK(lpc18xx_data->duty_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) LPC18XX_PWM_EVSTATEMSK_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (pwm_get_polarity(pwm) == PWM_POLARITY_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) set_event = lpc18xx_pwm->period_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) clear_event = lpc18xx_data->duty_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) res_action = LPC18XX_PWM_RES_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) set_event = lpc18xx_data->duty_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) clear_event = lpc18xx_pwm->period_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) res_action = LPC18XX_PWM_RES_CLEAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTSET(pwm->hwpwm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) BIT(set_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTCL(pwm->hwpwm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) BIT(clear_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) lpc18xx_pwm_set_conflict_res(lpc18xx_pwm, pwm, res_action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static void lpc18xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTSET(pwm->hwpwm), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTCL(pwm->hwpwm), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned long event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) event = find_first_zero_bit(&lpc18xx_pwm->event_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) LPC18XX_PWM_EVENT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (event >= LPC18XX_PWM_EVENT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_err(lpc18xx_pwm->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) "maximum number of simultaneous channels reached\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) set_bit(event, &lpc18xx_pwm->event_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) lpc18xx_data->duty_event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static void lpc18xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) clear_bit(lpc18xx_data->duty_event, &lpc18xx_pwm->event_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static const struct pwm_ops lpc18xx_pwm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .config = lpc18xx_pwm_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .set_polarity = lpc18xx_pwm_set_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .enable = lpc18xx_pwm_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .disable = lpc18xx_pwm_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .request = lpc18xx_pwm_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .free = lpc18xx_pwm_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static const struct of_device_id lpc18xx_pwm_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { .compatible = "nxp,lpc1850-sct-pwm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int lpc18xx_pwm_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct lpc18xx_pwm_chip *lpc18xx_pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct pwm_device *pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) lpc18xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*lpc18xx_pwm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!lpc18xx_pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) lpc18xx_pwm->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) lpc18xx_pwm->base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (IS_ERR(lpc18xx_pwm->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return PTR_ERR(lpc18xx_pwm->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) lpc18xx_pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (IS_ERR(lpc18xx_pwm->pwm_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dev_err(&pdev->dev, "failed to get pwm clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return PTR_ERR(lpc18xx_pwm->pwm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ret = clk_prepare_enable(lpc18xx_pwm->pwm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dev_err(&pdev->dev, "could not prepare or enable pwm clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) lpc18xx_pwm->clk_rate = clk_get_rate(lpc18xx_pwm->pwm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!lpc18xx_pwm->clk_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dev_err(&pdev->dev, "pwm clock has no frequency\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto disable_pwmclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mutex_init(&lpc18xx_pwm->res_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mutex_init(&lpc18xx_pwm->period_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) do_div(val, lpc18xx_pwm->clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) lpc18xx_pwm->max_period_ns = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) lpc18xx_pwm->clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) lpc18xx_pwm->chip.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) lpc18xx_pwm->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) lpc18xx_pwm->chip.npwm = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) lpc18xx_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) lpc18xx_pwm->chip.of_pwm_n_cells = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* SCT counter must be in unify (32 bit) mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) LPC18XX_PWM_CONFIG_UNIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * Everytime the timer counter reaches the period value, the related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * event will be triggered and the counter reset to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) set_bit(LPC18XX_PWM_EVENT_PERIOD, &lpc18xx_pwm->event_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) lpc18xx_pwm->period_event = LPC18XX_PWM_EVENT_PERIOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) LPC18XX_PWM_EVSTATEMSK(lpc18xx_pwm->period_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) LPC18XX_PWM_EVSTATEMSK_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) val = LPC18XX_PWM_EVCTRL_MATCH(lpc18xx_pwm->period_event) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) LPC18XX_PWM_EVCTRL_COMB_MATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) lpc18xx_pwm_writel(lpc18xx_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) LPC18XX_PWM_EVCTRL(lpc18xx_pwm->period_event), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) BIT(lpc18xx_pwm->period_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct lpc18xx_pwm_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) pwm = &lpc18xx_pwm->chip.pwms[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) data = devm_kzalloc(lpc18xx_pwm->dev, sizeof(*data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto disable_pwmclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pwm_set_chip_data(pwm, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) val &= ~LPC18XX_PWM_BIDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) val &= ~LPC18XX_PWM_CTRL_HALT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) val &= ~LPC18XX_PWM_PRE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) val |= LPC18XX_PWM_PRE(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret = pwmchip_add(&lpc18xx_pwm->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) goto disable_pwmclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) platform_set_drvdata(pdev, lpc18xx_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) disable_pwmclk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static int lpc18xx_pwm_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) val | LPC18XX_PWM_CTRL_HALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return pwmchip_remove(&lpc18xx_pwm->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static struct platform_driver lpc18xx_pwm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .name = "lpc18xx-sct-pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .of_match_table = lpc18xx_pwm_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .probe = lpc18xx_pwm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .remove = lpc18xx_pwm_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) module_platform_driver(lpc18xx_pwm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) MODULE_AUTHOR("Ariel D'Alessandro <ariel@vanguardiasur.com.ar>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) MODULE_DESCRIPTION("NXP LPC18xx PWM driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) MODULE_LICENSE("GPL v2");