Lines Matching +full:pc +full:- +full:ack

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2013-2016 STMicroelectronics (R&D) Limited
59 * Each capture input can be programmed to detect rising-edge, falling-edge,
123 static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period, in sti_pwm_get_prescale() argument
126 struct sti_pwm_compat_data *cdata = pc->cdata; in sti_pwm_get_prescale()
131 clk_rate = clk_get_rate(pc->pwm_clk); in sti_pwm_get_prescale()
133 dev_err(pc->dev, "failed to get clock rate\n"); in sti_pwm_get_prescale()
134 return -EINVAL; in sti_pwm_get_prescale()
138 * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_cnt + 1)) - 1 in sti_pwm_get_prescale()
141 value *= cdata->max_pwm_cnt + 1; in sti_pwm_get_prescale()
144 return -EINVAL; in sti_pwm_get_prescale()
146 ps = period / value - 1; in sti_pwm_get_prescale()
147 if (ps > cdata->max_prescale) in sti_pwm_get_prescale()
148 return -EINVAL; in sti_pwm_get_prescale()
167 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); in sti_pwm_config() local
168 struct sti_pwm_compat_data *cdata = pc->cdata; in sti_pwm_config()
170 struct pwm_device *cur = pc->cur; in sti_pwm_config()
171 struct device *dev = pc->dev; in sti_pwm_config()
175 ncfg = hweight_long(pc->configured); in sti_pwm_config()
192 ((ncfg == 1) && (pwm->hwpwm == cur->hwpwm)) || in sti_pwm_config()
193 ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) || in sti_pwm_config()
196 ret = clk_enable(pc->pwm_clk); in sti_pwm_config()
200 ret = clk_enable(pc->cpt_clk); in sti_pwm_config()
205 ret = sti_pwm_get_prescale(pc, period_ns, &prescale); in sti_pwm_config()
211 ret = regmap_field_write(pc->prescale_low, value); in sti_pwm_config()
217 ret = regmap_field_write(pc->prescale_high, value); in sti_pwm_config()
228 value = cdata->max_pwm_cnt * duty_ns / period_ns; in sti_pwm_config()
230 ret = regmap_write(pc->regmap, PWM_OUT_VAL(pwm->hwpwm), value); in sti_pwm_config()
234 ret = regmap_field_write(pc->pwm_cpt_int_en, 0); in sti_pwm_config()
236 set_bit(pwm->hwpwm, &pc->configured); in sti_pwm_config()
237 pc->cur = pwm; in sti_pwm_config()
242 return -EINVAL; in sti_pwm_config()
246 clk_disable(pc->pwm_clk); in sti_pwm_config()
247 clk_disable(pc->cpt_clk); in sti_pwm_config()
253 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); in sti_pwm_enable() local
254 struct device *dev = pc->dev; in sti_pwm_enable()
261 mutex_lock(&pc->sti_pwm_lock); in sti_pwm_enable()
263 if (!pc->en_count) { in sti_pwm_enable()
264 ret = clk_enable(pc->pwm_clk); in sti_pwm_enable()
268 ret = clk_enable(pc->cpt_clk); in sti_pwm_enable()
272 ret = regmap_field_write(pc->pwm_out_en, 1); in sti_pwm_enable()
275 pwm->hwpwm, ret); in sti_pwm_enable()
280 pc->en_count++; in sti_pwm_enable()
283 mutex_unlock(&pc->sti_pwm_lock); in sti_pwm_enable()
289 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); in sti_pwm_disable() local
291 mutex_lock(&pc->sti_pwm_lock); in sti_pwm_disable()
293 if (--pc->en_count) { in sti_pwm_disable()
294 mutex_unlock(&pc->sti_pwm_lock); in sti_pwm_disable()
298 regmap_field_write(pc->pwm_out_en, 0); in sti_pwm_disable()
300 clk_disable(pc->pwm_clk); in sti_pwm_disable()
301 clk_disable(pc->cpt_clk); in sti_pwm_disable()
303 mutex_unlock(&pc->sti_pwm_lock); in sti_pwm_disable()
308 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); in sti_pwm_free() local
310 clear_bit(pwm->hwpwm, &pc->configured); in sti_pwm_free()
316 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); in sti_pwm_capture() local
317 struct sti_pwm_compat_data *cdata = pc->cdata; in sti_pwm_capture()
318 struct sti_cpt_ddata *ddata = &cdata->ddata[pwm->hwpwm]; in sti_pwm_capture()
319 struct device *dev = pc->dev; in sti_pwm_capture()
324 if (pwm->hwpwm >= cdata->cpt_num_devs) { in sti_pwm_capture()
325 dev_err(dev, "device %u is not valid\n", pwm->hwpwm); in sti_pwm_capture()
326 return -EINVAL; in sti_pwm_capture()
329 mutex_lock(&ddata->lock); in sti_pwm_capture()
330 ddata->index = 0; in sti_pwm_capture()
333 regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_RISING); in sti_pwm_capture()
334 regmap_field_write(pc->pwm_cpt_int_en, BIT(pwm->hwpwm)); in sti_pwm_capture()
337 ret = regmap_field_write(pc->pwm_cpt_en, 1); in sti_pwm_capture()
340 pwm->hwpwm, ret); in sti_pwm_capture()
344 ret = wait_event_interruptible_timeout(ddata->wait, ddata->index > 1, in sti_pwm_capture()
347 regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_DISABLED); in sti_pwm_capture()
349 if (ret == -ERESTARTSYS) in sti_pwm_capture()
352 switch (ddata->index) { in sti_pwm_capture()
357 * - input signal is constant of less than 1 Hz in sti_pwm_capture()
358 * - there is no input signal at all in sti_pwm_capture()
362 result->period = 0; in sti_pwm_capture()
363 result->duty_cycle = 0; in sti_pwm_capture()
369 high = ddata->snapshot[1] - ddata->snapshot[0]; in sti_pwm_capture()
370 low = ddata->snapshot[2] - ddata->snapshot[1]; in sti_pwm_capture()
372 effective_ticks = clk_get_rate(pc->cpt_clk); in sti_pwm_capture()
374 result->period = (high + low) * NSEC_PER_SEC; in sti_pwm_capture()
375 result->period /= effective_ticks; in sti_pwm_capture()
377 result->duty_cycle = high * NSEC_PER_SEC; in sti_pwm_capture()
378 result->duty_cycle /= effective_ticks; in sti_pwm_capture()
389 regmap_field_write(pc->pwm_cpt_en, 0); in sti_pwm_capture()
391 mutex_unlock(&ddata->lock); in sti_pwm_capture()
398 struct sti_pwm_chip *pc = to_sti_pwmchip(chip); in sti_pwm_apply() local
399 struct sti_pwm_compat_data *cdata = pc->cdata; in sti_pwm_apply()
400 struct device *dev = pc->dev; in sti_pwm_apply()
403 if (pwm->hwpwm >= cdata->pwm_num_devs) { in sti_pwm_apply()
405 pwm->hwpwm); in sti_pwm_apply()
406 return -EINVAL; in sti_pwm_apply()
409 if (state->polarity != PWM_POLARITY_NORMAL) in sti_pwm_apply()
410 return -EINVAL; in sti_pwm_apply()
412 if (!state->enabled) { in sti_pwm_apply()
413 if (pwm->state.enabled) in sti_pwm_apply()
419 err = sti_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); in sti_pwm_apply()
423 if (!pwm->state.enabled) in sti_pwm_apply()
438 struct sti_pwm_chip *pc = data; in sti_pwm_interrupt() local
439 struct device *dev = pc->dev; in sti_pwm_interrupt()
446 ret = regmap_field_read(pc->pwm_cpt_int_stat, &cpt_int_stat); in sti_pwm_interrupt()
451 devicenum = ffs(cpt_int_stat) - 1; in sti_pwm_interrupt()
453 ddata = &pc->cdata->ddata[devicenum]; in sti_pwm_interrupt()
471 regmap_read(pc->regmap, in sti_pwm_interrupt()
473 &ddata->snapshot[ddata->index]); in sti_pwm_interrupt()
475 switch (ddata->index) { in sti_pwm_interrupt()
478 regmap_read(pc->regmap, PWM_CPT_EDGE(devicenum), &reg); in sti_pwm_interrupt()
480 regmap_write(pc->regmap, PWM_CPT_EDGE(devicenum), reg); in sti_pwm_interrupt()
482 ddata->index++; in sti_pwm_interrupt()
486 regmap_write(pc->regmap, in sti_pwm_interrupt()
489 wake_up(&ddata->wait); in sti_pwm_interrupt()
501 /* Just ACK everything */ in sti_pwm_interrupt()
502 regmap_write(pc->regmap, PWM_INT_ACK, PWM_INT_ACK_MASK); in sti_pwm_interrupt()
507 static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) in sti_pwm_probe_dt() argument
509 struct device *dev = pc->dev; in sti_pwm_probe_dt()
511 struct device_node *np = dev->of_node; in sti_pwm_probe_dt()
512 struct sti_pwm_compat_data *cdata = pc->cdata; in sti_pwm_probe_dt()
516 ret = of_property_read_u32(np, "st,pwm-num-chan", &num_devs); in sti_pwm_probe_dt()
518 cdata->pwm_num_devs = num_devs; in sti_pwm_probe_dt()
520 ret = of_property_read_u32(np, "st,capture-num-chan", &num_devs); in sti_pwm_probe_dt()
522 cdata->cpt_num_devs = num_devs; in sti_pwm_probe_dt()
524 if (!cdata->pwm_num_devs && !cdata->cpt_num_devs) { in sti_pwm_probe_dt()
526 return -EINVAL; in sti_pwm_probe_dt()
529 reg_fields = cdata->reg_fields; in sti_pwm_probe_dt()
531 pc->prescale_low = devm_regmap_field_alloc(dev, pc->regmap, in sti_pwm_probe_dt()
533 if (IS_ERR(pc->prescale_low)) in sti_pwm_probe_dt()
534 return PTR_ERR(pc->prescale_low); in sti_pwm_probe_dt()
536 pc->prescale_high = devm_regmap_field_alloc(dev, pc->regmap, in sti_pwm_probe_dt()
538 if (IS_ERR(pc->prescale_high)) in sti_pwm_probe_dt()
539 return PTR_ERR(pc->prescale_high); in sti_pwm_probe_dt()
541 pc->pwm_out_en = devm_regmap_field_alloc(dev, pc->regmap, in sti_pwm_probe_dt()
543 if (IS_ERR(pc->pwm_out_en)) in sti_pwm_probe_dt()
544 return PTR_ERR(pc->pwm_out_en); in sti_pwm_probe_dt()
546 pc->pwm_cpt_en = devm_regmap_field_alloc(dev, pc->regmap, in sti_pwm_probe_dt()
548 if (IS_ERR(pc->pwm_cpt_en)) in sti_pwm_probe_dt()
549 return PTR_ERR(pc->pwm_cpt_en); in sti_pwm_probe_dt()
551 pc->pwm_cpt_int_en = devm_regmap_field_alloc(dev, pc->regmap, in sti_pwm_probe_dt()
553 if (IS_ERR(pc->pwm_cpt_int_en)) in sti_pwm_probe_dt()
554 return PTR_ERR(pc->pwm_cpt_int_en); in sti_pwm_probe_dt()
556 pc->pwm_cpt_int_stat = devm_regmap_field_alloc(dev, pc->regmap, in sti_pwm_probe_dt()
558 if (PTR_ERR_OR_ZERO(pc->pwm_cpt_int_stat)) in sti_pwm_probe_dt()
559 return PTR_ERR(pc->pwm_cpt_int_stat); in sti_pwm_probe_dt()
572 struct device *dev = &pdev->dev; in sti_pwm_probe()
575 struct sti_pwm_chip *pc; in sti_pwm_probe() local
579 pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); in sti_pwm_probe()
580 if (!pc) in sti_pwm_probe()
581 return -ENOMEM; in sti_pwm_probe()
582 chip = &pc->chip; in sti_pwm_probe()
586 return -ENOMEM; in sti_pwm_probe()
588 pc->mmio = devm_platform_ioremap_resource(pdev, 0); in sti_pwm_probe()
589 if (IS_ERR(pc->mmio)) in sti_pwm_probe()
590 return PTR_ERR(pc->mmio); in sti_pwm_probe()
592 pc->regmap = devm_regmap_init_mmio(dev, pc->mmio, in sti_pwm_probe()
594 if (IS_ERR(pc->regmap)) in sti_pwm_probe()
595 return PTR_ERR(pc->regmap); in sti_pwm_probe()
601 ret = devm_request_irq(&pdev->dev, irq, sti_pwm_interrupt, 0, in sti_pwm_probe()
602 pdev->name, pc); in sti_pwm_probe()
604 dev_err(&pdev->dev, "Failed to request IRQ\n"); in sti_pwm_probe()
612 cdata->reg_fields = sti_pwm_regfields; in sti_pwm_probe()
613 cdata->max_prescale = 0xff; in sti_pwm_probe()
614 cdata->max_pwm_cnt = 255; in sti_pwm_probe()
615 cdata->pwm_num_devs = 0; in sti_pwm_probe()
616 cdata->cpt_num_devs = 0; in sti_pwm_probe()
618 pc->cdata = cdata; in sti_pwm_probe()
619 pc->dev = dev; in sti_pwm_probe()
620 pc->en_count = 0; in sti_pwm_probe()
621 mutex_init(&pc->sti_pwm_lock); in sti_pwm_probe()
623 ret = sti_pwm_probe_dt(pc); in sti_pwm_probe()
627 if (cdata->pwm_num_devs) { in sti_pwm_probe()
628 pc->pwm_clk = devm_clk_get_prepared(dev, "pwm"); in sti_pwm_probe()
629 if (IS_ERR(pc->pwm_clk)) { in sti_pwm_probe()
631 return PTR_ERR(pc->pwm_clk); in sti_pwm_probe()
635 if (cdata->cpt_num_devs) { in sti_pwm_probe()
636 pc->cpt_clk = devm_clk_get_prepared(dev, "capture"); in sti_pwm_probe()
637 if (IS_ERR(pc->cpt_clk)) { in sti_pwm_probe()
639 return PTR_ERR(pc->cpt_clk); in sti_pwm_probe()
642 cdata->ddata = devm_kzalloc(dev, cdata->cpt_num_devs * sizeof(*cdata->ddata), GFP_KERNEL); in sti_pwm_probe()
643 if (!cdata->ddata) in sti_pwm_probe()
644 return -ENOMEM; in sti_pwm_probe()
647 chip->dev = dev; in sti_pwm_probe()
648 chip->ops = &sti_pwm_ops; in sti_pwm_probe()
649 chip->npwm = max(cdata->pwm_num_devs, cdata->cpt_num_devs); in sti_pwm_probe()
651 for (i = 0; i < cdata->cpt_num_devs; i++) { in sti_pwm_probe()
652 struct sti_cpt_ddata *ddata = &cdata->ddata[i]; in sti_pwm_probe()
654 init_waitqueue_head(&ddata->wait); in sti_pwm_probe()
655 mutex_init(&ddata->lock); in sti_pwm_probe()
662 { .compatible = "st,sti-pwm", },
669 .name = "sti-pwm",