Lines Matching +full:off +full:- +full:chip
1 // SPDX-License-Identifier: GPL-2.0-only
8 * This driver is a complete rewrite of the former pwm-twl6030.c authorded by:
15 * - The twl6030 hardware only supports two period lengths (128 clock ticks and
17 * - The hardware doesn't support ON = 0, so the active part of a period doesn't
19 * - The hardware could support inverted polarity (with a similar limitation as
21 * - The hardware emits a constant low output when disabled.
22 * - A request for .duty_cycle = 0 results in an output wave with one active
24 * - The driver only implements setting the relative duty cycle.
25 * - The driver doesn't implement .get_state().
38 * - LEDA uses PWMA
39 * - LEDB uses PWMB
65 struct pwm_chip chip; member
69 static inline struct twl_pwmled_chip *to_twl(struct pwm_chip *chip) in to_twl() argument
71 return container_of(chip, struct twl_pwmled_chip, chip); in to_twl()
74 static int twl4030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, in twl4030_pwmled_config() argument
83 * On-cycle is set to 1 (the minimum allowed value) in twl4030_pwmled_config()
84 * The off time of 0 is not configurable, so the mapping is: in twl4030_pwmled_config()
85 * 0 -> off cycle = 2, in twl4030_pwmled_config()
86 * 1 -> off cycle = 2, in twl4030_pwmled_config()
87 * 2 -> off cycle = 3, in twl4030_pwmled_config()
88 * 126 - > off cycle 127, in twl4030_pwmled_config()
89 * 127 - > off cycle 1 in twl4030_pwmled_config()
90 * When on cycle == off cycle the PWM will be always on in twl4030_pwmled_config()
97 base = pwm->hwpwm * 2 + TWL4030_PWMA_REG; in twl4030_pwmled_config()
103 dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); in twl4030_pwmled_config()
108 static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) in twl4030_pwmled_enable() argument
110 struct twl_pwmled_chip *twl = to_twl(chip); in twl4030_pwmled_enable()
114 mutex_lock(&twl->mutex); in twl4030_pwmled_enable()
117 dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label); in twl4030_pwmled_enable()
121 val |= TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS); in twl4030_pwmled_enable()
125 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); in twl4030_pwmled_enable()
128 mutex_unlock(&twl->mutex); in twl4030_pwmled_enable()
132 static void twl4030_pwmled_disable(struct pwm_chip *chip, in twl4030_pwmled_disable() argument
135 struct twl_pwmled_chip *twl = to_twl(chip); in twl4030_pwmled_disable()
139 mutex_lock(&twl->mutex); in twl4030_pwmled_disable()
142 dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label); in twl4030_pwmled_disable()
146 val &= ~TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS); in twl4030_pwmled_disable()
150 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); in twl4030_pwmled_disable()
153 mutex_unlock(&twl->mutex); in twl4030_pwmled_disable()
156 static int twl4030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, in twl4030_pwmled_apply() argument
161 if (state->polarity != PWM_POLARITY_NORMAL) in twl4030_pwmled_apply()
162 return -EINVAL; in twl4030_pwmled_apply()
164 if (!state->enabled) { in twl4030_pwmled_apply()
165 if (pwm->state.enabled) in twl4030_pwmled_apply()
166 twl4030_pwmled_disable(chip, pwm); in twl4030_pwmled_apply()
172 * We cannot skip calling ->config even if state->period == in twl4030_pwmled_apply()
173 * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle in twl4030_pwmled_apply()
175 * pwm_apply_might_sleep because of !state->enabled and so the two values in in twl4030_pwmled_apply()
176 * pwm->state might not be configured in hardware. in twl4030_pwmled_apply()
178 ret = twl4030_pwmled_config(pwm->chip, pwm, in twl4030_pwmled_apply()
179 state->duty_cycle, state->period); in twl4030_pwmled_apply()
183 if (!pwm->state.enabled) in twl4030_pwmled_apply()
184 ret = twl4030_pwmled_enable(chip, pwm); in twl4030_pwmled_apply()
195 static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, in twl6030_pwmled_config() argument
207 dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); in twl6030_pwmled_config()
212 static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) in twl6030_pwmled_enable() argument
214 struct twl_pwmled_chip *twl = to_twl(chip); in twl6030_pwmled_enable()
218 mutex_lock(&twl->mutex); in twl6030_pwmled_enable()
221 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", in twl6030_pwmled_enable()
222 pwm->label); in twl6030_pwmled_enable()
231 dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); in twl6030_pwmled_enable()
234 mutex_unlock(&twl->mutex); in twl6030_pwmled_enable()
238 static void twl6030_pwmled_disable(struct pwm_chip *chip, in twl6030_pwmled_disable() argument
241 struct twl_pwmled_chip *twl = to_twl(chip); in twl6030_pwmled_disable()
245 mutex_lock(&twl->mutex); in twl6030_pwmled_disable()
248 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", in twl6030_pwmled_disable()
249 pwm->label); in twl6030_pwmled_disable()
258 dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); in twl6030_pwmled_disable()
261 mutex_unlock(&twl->mutex); in twl6030_pwmled_disable()
264 static int twl6030_pwmled_apply(struct pwm_chip *chip, struct pwm_device *pwm, in twl6030_pwmled_apply() argument
269 if (state->polarity != pwm->state.polarity) in twl6030_pwmled_apply()
270 return -EINVAL; in twl6030_pwmled_apply()
272 if (!state->enabled) { in twl6030_pwmled_apply()
273 if (pwm->state.enabled) in twl6030_pwmled_apply()
274 twl6030_pwmled_disable(chip, pwm); in twl6030_pwmled_apply()
279 err = twl6030_pwmled_config(pwm->chip, pwm, in twl6030_pwmled_apply()
280 state->duty_cycle, state->period); in twl6030_pwmled_apply()
284 if (!pwm->state.enabled) in twl6030_pwmled_apply()
285 err = twl6030_pwmled_enable(chip, pwm); in twl6030_pwmled_apply()
290 static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm) in twl6030_pwmled_request() argument
292 struct twl_pwmled_chip *twl = to_twl(chip); in twl6030_pwmled_request()
296 mutex_lock(&twl->mutex); in twl6030_pwmled_request()
299 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", in twl6030_pwmled_request()
300 pwm->label); in twl6030_pwmled_request()
309 dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label); in twl6030_pwmled_request()
312 mutex_unlock(&twl->mutex); in twl6030_pwmled_request()
316 static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm) in twl6030_pwmled_free() argument
318 struct twl_pwmled_chip *twl = to_twl(chip); in twl6030_pwmled_free()
322 mutex_lock(&twl->mutex); in twl6030_pwmled_free()
325 dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", in twl6030_pwmled_free()
326 pwm->label); in twl6030_pwmled_free()
335 dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label); in twl6030_pwmled_free()
338 mutex_unlock(&twl->mutex); in twl6030_pwmled_free()
352 twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); in twl_pwmled_probe()
354 return -ENOMEM; in twl_pwmled_probe()
357 twl->chip.ops = &twl4030_pwmled_ops; in twl_pwmled_probe()
358 twl->chip.npwm = 2; in twl_pwmled_probe()
360 twl->chip.ops = &twl6030_pwmled_ops; in twl_pwmled_probe()
361 twl->chip.npwm = 1; in twl_pwmled_probe()
364 twl->chip.dev = &pdev->dev; in twl_pwmled_probe()
366 mutex_init(&twl->mutex); in twl_pwmled_probe()
368 return devm_pwmchip_add(&pdev->dev, &twl->chip); in twl_pwmled_probe()
373 { .compatible = "ti,twl4030-pwmled" },
374 { .compatible = "ti,twl6030-pwmled" },
382 .name = "twl-pwmled",
391 MODULE_ALIAS("platform:twl-pwmled");