Lines Matching +full:duty +full:- +full:cycle
1 // SPDX-License-Identifier: GPL-2.0-only
9 * Also based on pwm-samsung.c
13 * PWM driver / controller, using the OMAP's dual-mode timers
20 * - When PWM is stopped, timer counter gets stopped immediately. This
22 * - When PWM is running and changing both duty cycle and period,
27 * - period for current cycle = current_period + new period
28 * - duty_cycle for current period = current period + new duty_cycle.
29 * - PWM OMAP DM timer cannot change the polarity when pwm is active. When
31 * - PWM is stopped abruptly(without completing the current cycle)
32 * - Polarity is changed
33 * - A fresh cycle is started.
42 #include <clocksource/timer-ti-dm.h>
43 #include <linux/platform_data/dmtimer-omap.h>
54 * struct pwm_omap_dmtimer_chip - Structure representing a pwm chip
74 * pwm_omap_dmtimer_get_clock_cycles() - Get clock cycles in a time frame
86 * pwm_omap_dmtimer_start() - Start the pwm omap dm timer in pwm mode
99 omap->pdata->enable(omap->dm_timer); in pwm_omap_dmtimer_start()
100 omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN); in pwm_omap_dmtimer_start()
101 omap->pdata->disable(omap->dm_timer); in pwm_omap_dmtimer_start()
103 omap->pdata->start(omap->dm_timer); in pwm_omap_dmtimer_start()
107 * pwm_omap_dmtimer_is_enabled() - Detect if the pwm is enabled.
116 status = omap->pdata->get_pwm_status(omap->dm_timer); in pwm_omap_dmtimer_is_enabled()
122 * pwm_omap_dmtimer_polarity() - Detect the polarity of pwm.
131 status = omap->pdata->get_pwm_status(omap->dm_timer); in pwm_omap_dmtimer_polarity()
137 * pwm_omap_dmtimer_config() - Update the configuration of pwm omap dm timer
140 * @duty_ns: New duty cycle in nano seconds
156 dev_dbg(pwmchip_parent(chip), "requested duty cycle: %d ns, period: %d ns\n", in pwm_omap_dmtimer_config()
163 fclk = omap->pdata->get_fclk(omap->dm_timer); in pwm_omap_dmtimer_config()
166 return -EINVAL; in pwm_omap_dmtimer_config()
172 return -EINVAL; in pwm_omap_dmtimer_config()
179 * specified period and duty cycle. The load value determines the in pwm_omap_dmtimer_config()
180 * period time and the match value determines the duty time. in pwm_omap_dmtimer_config()
182 * The period lasts for (DM_TIMER_MAX-load_value+1) clock cycles. in pwm_omap_dmtimer_config()
183 * Similarly, the active time lasts (match_value-load_value+1) cycles. in pwm_omap_dmtimer_config()
184 * The non-active time is the remainder: (DM_TIMER_MAX-match_value) in pwm_omap_dmtimer_config()
200 return -EINVAL; in pwm_omap_dmtimer_config()
205 "duty cycle %d ns is too short for clock rate %lu Hz\n", in pwm_omap_dmtimer_config()
207 dev_dbg(pwmchip_parent(chip), "using minimum of 1 clock cycle\n"); in pwm_omap_dmtimer_config()
211 "duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n", in pwm_omap_dmtimer_config()
213 dev_dbg(pwmchip_parent(chip), "using maximum of 1 clock cycle less than period\n"); in pwm_omap_dmtimer_config()
214 duty_cycles = period_cycles - 1; in pwm_omap_dmtimer_config()
217 dev_dbg(pwmchip_parent(chip), "effective duty cycle: %lld ns, period: %lld ns\n", in pwm_omap_dmtimer_config()
223 load_value = (DM_TIMER_MAX - period_cycles) + 1; in pwm_omap_dmtimer_config()
224 match_value = load_value + duty_cycles - 1; in pwm_omap_dmtimer_config()
226 omap->pdata->set_load(omap->dm_timer, load_value); in pwm_omap_dmtimer_config()
227 omap->pdata->set_match(omap->dm_timer, true, match_value); in pwm_omap_dmtimer_config()
236 * pwm_omap_dmtimer_set_polarity() - Changes the polarity of the pwm dm timer.
251 omap->pdata->stop(omap->dm_timer); in pwm_omap_dmtimer_set_polarity()
253 omap->pdata->set_pwm(omap->dm_timer, in pwm_omap_dmtimer_set_polarity()
263 * pwm_omap_dmtimer_apply() - Changes the state of the pwm omap dm timer.
277 if (pwm_omap_dmtimer_is_enabled(omap) && !state->enabled) { in pwm_omap_dmtimer_apply()
278 omap->pdata->stop(omap->dm_timer); in pwm_omap_dmtimer_apply()
282 if (pwm_omap_dmtimer_polarity(omap) != state->polarity) in pwm_omap_dmtimer_apply()
283 pwm_omap_dmtimer_set_polarity(chip, pwm, state->polarity); in pwm_omap_dmtimer_apply()
285 ret = pwm_omap_dmtimer_config(chip, pwm, state->duty_cycle, in pwm_omap_dmtimer_apply()
286 state->period); in pwm_omap_dmtimer_apply()
290 if (!pwm_omap_dmtimer_is_enabled(omap) && state->enabled) { in pwm_omap_dmtimer_apply()
291 omap->pdata->set_pwm(omap->dm_timer, in pwm_omap_dmtimer_apply()
292 state->polarity == PWM_POLARITY_INVERSED, in pwm_omap_dmtimer_apply()
308 struct device_node *np = pdev->dev.of_node; in pwm_omap_dmtimer_probe()
321 return -ENODEV; in pwm_omap_dmtimer_probe()
325 dev_err(&pdev->dev, "Unable to find Timer pdev\n"); in pwm_omap_dmtimer_probe()
326 ret = -ENODEV; in pwm_omap_dmtimer_probe()
330 timer_pdata = dev_get_platdata(&timer_pdev->dev); in pwm_omap_dmtimer_probe()
332 dev_dbg(&pdev->dev, in pwm_omap_dmtimer_probe()
334 ret = -EPROBE_DEFER; in pwm_omap_dmtimer_probe()
338 pdata = timer_pdata->timer_ops; in pwm_omap_dmtimer_probe()
340 if (!pdata || !pdata->request_by_node || in pwm_omap_dmtimer_probe()
341 !pdata->free || in pwm_omap_dmtimer_probe()
342 !pdata->enable || in pwm_omap_dmtimer_probe()
343 !pdata->disable || in pwm_omap_dmtimer_probe()
344 !pdata->get_fclk || in pwm_omap_dmtimer_probe()
345 !pdata->start || in pwm_omap_dmtimer_probe()
346 !pdata->stop || in pwm_omap_dmtimer_probe()
347 !pdata->set_load || in pwm_omap_dmtimer_probe()
348 !pdata->set_match || in pwm_omap_dmtimer_probe()
349 !pdata->set_pwm || in pwm_omap_dmtimer_probe()
350 !pdata->get_pwm_status || in pwm_omap_dmtimer_probe()
351 !pdata->set_prescaler || in pwm_omap_dmtimer_probe()
352 !pdata->write_counter) { in pwm_omap_dmtimer_probe()
353 dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); in pwm_omap_dmtimer_probe()
354 ret = -EINVAL; in pwm_omap_dmtimer_probe()
358 if (!of_property_read_bool(timer, "ti,timer-pwm")) { in pwm_omap_dmtimer_probe()
359 dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); in pwm_omap_dmtimer_probe()
360 ret = -ENODEV; in pwm_omap_dmtimer_probe()
364 dm_timer = pdata->request_by_node(timer); in pwm_omap_dmtimer_probe()
366 ret = -EPROBE_DEFER; in pwm_omap_dmtimer_probe()
370 chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*omap)); in pwm_omap_dmtimer_probe()
377 omap->pdata = pdata; in pwm_omap_dmtimer_probe()
378 omap->dm_timer = dm_timer; in pwm_omap_dmtimer_probe()
379 omap->dm_timer_pdev = timer_pdev; in pwm_omap_dmtimer_probe()
385 if (pm_runtime_active(&omap->dm_timer_pdev->dev)) in pwm_omap_dmtimer_probe()
386 omap->pdata->stop(omap->dm_timer); in pwm_omap_dmtimer_probe()
388 if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v)) in pwm_omap_dmtimer_probe()
389 omap->pdata->set_prescaler(omap->dm_timer, v); in pwm_omap_dmtimer_probe()
392 if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v)) in pwm_omap_dmtimer_probe()
393 omap->pdata->set_source(omap->dm_timer, v); in pwm_omap_dmtimer_probe()
395 chip->ops = &pwm_omap_dmtimer_ops; in pwm_omap_dmtimer_probe()
399 dev_err(&pdev->dev, "failed to register PWM\n"); in pwm_omap_dmtimer_probe()
417 pdata->free(dm_timer); in pwm_omap_dmtimer_probe()
423 put_device(&timer_pdev->dev); in pwm_omap_dmtimer_probe()
438 if (pm_runtime_active(&omap->dm_timer_pdev->dev)) in pwm_omap_dmtimer_remove()
439 omap->pdata->stop(omap->dm_timer); in pwm_omap_dmtimer_remove()
441 omap->pdata->free(omap->dm_timer); in pwm_omap_dmtimer_remove()
443 put_device(&omap->dm_timer_pdev->dev); in pwm_omap_dmtimer_remove()
447 {.compatible = "ti,omap-dmtimer-pwm"},
454 .name = "omap-dmtimer-pwm",
466 MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers");