Lines Matching +full:at91rm9200 +full:- +full:tcb

1 // SPDX-License-Identifier: GPL-2.0-only
73 struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_request()
77 ret = clk_prepare_enable(tcbpwmc->clk); in atmel_tcb_pwm_request()
81 tcbpwm->duty = 0; in atmel_tcb_pwm_request()
82 tcbpwm->period = 0; in atmel_tcb_pwm_request()
83 tcbpwm->div = 0; in atmel_tcb_pwm_request()
85 guard(spinlock)(&tcbpwmc->lock); in atmel_tcb_pwm_request()
87 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); in atmel_tcb_pwm_request()
93 if (pwm->hwpwm == 0) in atmel_tcb_pwm_request()
94 regmap_read(tcbpwmc->regmap, in atmel_tcb_pwm_request()
95 ATMEL_TC_REG(tcbpwmc->channel, RA), in atmel_tcb_pwm_request()
96 &tcbpwm->duty); in atmel_tcb_pwm_request()
98 regmap_read(tcbpwmc->regmap, in atmel_tcb_pwm_request()
99 ATMEL_TC_REG(tcbpwmc->channel, RB), in atmel_tcb_pwm_request()
100 &tcbpwm->duty); in atmel_tcb_pwm_request()
102 tcbpwm->div = cmr & ATMEL_TC_TCCLKS; in atmel_tcb_pwm_request()
103 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, RC), in atmel_tcb_pwm_request()
104 &tcbpwm->period); in atmel_tcb_pwm_request()
111 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); in atmel_tcb_pwm_request()
120 clk_disable_unprepare(tcbpwmc->clk); in atmel_tcb_pwm_free()
127 struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_disable()
133 * - set output to high if PWM_POLARITY_INVERSED in atmel_tcb_pwm_disable()
134 * - set output to low if PWM_POLARITY_NORMAL in atmel_tcb_pwm_disable()
138 if (tcbpwm->duty == 0) in atmel_tcb_pwm_disable()
141 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); in atmel_tcb_pwm_disable()
144 if (pwm->hwpwm == 0) { in atmel_tcb_pwm_disable()
158 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); in atmel_tcb_pwm_disable()
165 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_disable()
166 ATMEL_TC_REG(tcbpwmc->channel, CCR), in atmel_tcb_pwm_disable()
168 tcbpwmc->bkup.enabled = 1; in atmel_tcb_pwm_disable()
170 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_disable()
171 ATMEL_TC_REG(tcbpwmc->channel, CCR), in atmel_tcb_pwm_disable()
173 tcbpwmc->bkup.enabled = 0; in atmel_tcb_pwm_disable()
181 struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_enable()
187 * - set output to high if PWM_POLARITY_INVERSED in atmel_tcb_pwm_enable()
188 * - set output to low if PWM_POLARITY_NORMAL in atmel_tcb_pwm_enable()
192 if (tcbpwm->duty == 0) in atmel_tcb_pwm_enable()
195 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); in atmel_tcb_pwm_enable()
200 if (pwm->hwpwm == 0) { in atmel_tcb_pwm_enable()
222 if (tcbpwm->duty != tcbpwm->period && tcbpwm->duty > 0) { in atmel_tcb_pwm_enable()
223 if (pwm->hwpwm == 0) { in atmel_tcb_pwm_enable()
236 cmr |= (tcbpwm->div & ATMEL_TC_TCCLKS); in atmel_tcb_pwm_enable()
238 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); in atmel_tcb_pwm_enable()
240 if (pwm->hwpwm == 0) in atmel_tcb_pwm_enable()
241 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_enable()
242 ATMEL_TC_REG(tcbpwmc->channel, RA), in atmel_tcb_pwm_enable()
243 tcbpwm->duty); in atmel_tcb_pwm_enable()
245 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_enable()
246 ATMEL_TC_REG(tcbpwmc->channel, RB), in atmel_tcb_pwm_enable()
247 tcbpwm->duty); in atmel_tcb_pwm_enable()
249 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, RC), in atmel_tcb_pwm_enable()
250 tcbpwm->period); in atmel_tcb_pwm_enable()
253 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CCR), in atmel_tcb_pwm_enable()
255 tcbpwmc->bkup.enabled = 1; in atmel_tcb_pwm_enable()
263 struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_config()
269 unsigned rate = clk_get_rate(tcbpwmc->clk); in atmel_tcb_pwm_config()
278 if (tcbpwmc->gclk) in atmel_tcb_pwm_config()
286 max = min << tcbpwmc->width; in atmel_tcb_pwm_config()
297 rate = clk_get_rate(tcbpwmc->slow_clk); in atmel_tcb_pwm_config()
299 max = min << tcbpwmc->width; in atmel_tcb_pwm_config()
303 return -ERANGE; in atmel_tcb_pwm_config()
309 if (pwm->hwpwm == 0) in atmel_tcb_pwm_config()
310 atcbpwm = &tcbpwmc->pwms[1]; in atmel_tcb_pwm_config()
312 atcbpwm = &tcbpwmc->pwms[0]; in atmel_tcb_pwm_config()
315 * PWM devices provided by the TCB driver are grouped by 2. in atmel_tcb_pwm_config()
322 if ((atcbpwm && atcbpwm->duty > 0 && in atmel_tcb_pwm_config()
323 atcbpwm->duty != atcbpwm->period) && in atmel_tcb_pwm_config()
324 (atcbpwm->div != i || atcbpwm->period != period)) { in atmel_tcb_pwm_config()
325 dev_err(chip->dev, in atmel_tcb_pwm_config()
327 return -EINVAL; in atmel_tcb_pwm_config()
330 tcbpwm->period = period; in atmel_tcb_pwm_config()
331 tcbpwm->div = i; in atmel_tcb_pwm_config()
332 tcbpwm->duty = duty; in atmel_tcb_pwm_config()
344 guard(spinlock)(&tcbpwmc->lock); in atmel_tcb_pwm_apply()
346 if (!state->enabled) { in atmel_tcb_pwm_apply()
347 atmel_tcb_pwm_disable(chip, pwm, state->polarity); in atmel_tcb_pwm_apply()
351 period = state->period < INT_MAX ? state->period : INT_MAX; in atmel_tcb_pwm_apply()
352 duty_cycle = state->duty_cycle < INT_MAX ? state->duty_cycle : INT_MAX; in atmel_tcb_pwm_apply()
358 return atmel_tcb_pwm_enable(chip, pwm, state->polarity); in atmel_tcb_pwm_apply()
382 { .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, },
383 { .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, },
384 { .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, },
393 struct device_node *np = pdev->dev.of_node; in atmel_tcb_pwm_probe()
398 tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); in atmel_tcb_pwm_probe()
400 return -ENOMEM; in atmel_tcb_pwm_probe()
404 dev_err(&pdev->dev, in atmel_tcb_pwm_probe()
410 tcbpwm->regmap = syscon_node_to_regmap(np->parent); in atmel_tcb_pwm_probe()
411 if (IS_ERR(tcbpwm->regmap)) in atmel_tcb_pwm_probe()
412 return PTR_ERR(tcbpwm->regmap); in atmel_tcb_pwm_probe()
414 tcbpwm->slow_clk = of_clk_get_by_name(np->parent, "slow_clk"); in atmel_tcb_pwm_probe()
415 if (IS_ERR(tcbpwm->slow_clk)) in atmel_tcb_pwm_probe()
416 return PTR_ERR(tcbpwm->slow_clk); in atmel_tcb_pwm_probe()
419 tcbpwm->clk = of_clk_get_by_name(np->parent, clk_name); in atmel_tcb_pwm_probe()
420 if (IS_ERR(tcbpwm->clk)) in atmel_tcb_pwm_probe()
421 tcbpwm->clk = of_clk_get_by_name(np->parent, "t0_clk"); in atmel_tcb_pwm_probe()
422 if (IS_ERR(tcbpwm->clk)) { in atmel_tcb_pwm_probe()
423 err = PTR_ERR(tcbpwm->clk); in atmel_tcb_pwm_probe()
427 match = of_match_node(atmel_tcb_of_match, np->parent); in atmel_tcb_pwm_probe()
428 config = match->data; in atmel_tcb_pwm_probe()
430 if (config->has_gclk) { in atmel_tcb_pwm_probe()
431 tcbpwm->gclk = of_clk_get_by_name(np->parent, "gclk"); in atmel_tcb_pwm_probe()
432 if (IS_ERR(tcbpwm->gclk)) { in atmel_tcb_pwm_probe()
433 err = PTR_ERR(tcbpwm->gclk); in atmel_tcb_pwm_probe()
438 tcbpwm->chip.dev = &pdev->dev; in atmel_tcb_pwm_probe()
439 tcbpwm->chip.ops = &atmel_tcb_pwm_ops; in atmel_tcb_pwm_probe()
440 tcbpwm->chip.npwm = NPWM; in atmel_tcb_pwm_probe()
441 tcbpwm->channel = channel; in atmel_tcb_pwm_probe()
442 tcbpwm->width = config->counter_width; in atmel_tcb_pwm_probe()
444 err = clk_prepare_enable(tcbpwm->slow_clk); in atmel_tcb_pwm_probe()
448 spin_lock_init(&tcbpwm->lock); in atmel_tcb_pwm_probe()
450 err = pwmchip_add(&tcbpwm->chip); in atmel_tcb_pwm_probe()
459 clk_disable_unprepare(tcbpwm->slow_clk); in atmel_tcb_pwm_probe()
462 clk_put(tcbpwm->gclk); in atmel_tcb_pwm_probe()
465 clk_put(tcbpwm->clk); in atmel_tcb_pwm_probe()
468 clk_put(tcbpwm->slow_clk); in atmel_tcb_pwm_probe()
477 pwmchip_remove(&tcbpwm->chip); in atmel_tcb_pwm_remove()
479 clk_disable_unprepare(tcbpwm->slow_clk); in atmel_tcb_pwm_remove()
480 clk_put(tcbpwm->gclk); in atmel_tcb_pwm_remove()
481 clk_put(tcbpwm->clk); in atmel_tcb_pwm_remove()
482 clk_put(tcbpwm->slow_clk); in atmel_tcb_pwm_remove()
486 { .compatible = "atmel,tcb-pwm", },
495 struct atmel_tcb_channel *chan = &tcbpwm->bkup; in atmel_tcb_pwm_suspend()
496 unsigned int channel = tcbpwm->channel; in atmel_tcb_pwm_suspend()
498 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, CMR), &chan->cmr); in atmel_tcb_pwm_suspend()
499 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, RA), &chan->ra); in atmel_tcb_pwm_suspend()
500 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, RB), &chan->rb); in atmel_tcb_pwm_suspend()
501 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, RC), &chan->rc); in atmel_tcb_pwm_suspend()
509 struct atmel_tcb_channel *chan = &tcbpwm->bkup; in atmel_tcb_pwm_resume()
510 unsigned int channel = tcbpwm->channel; in atmel_tcb_pwm_resume()
512 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, CMR), chan->cmr); in atmel_tcb_pwm_resume()
513 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, RA), chan->ra); in atmel_tcb_pwm_resume()
514 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, RB), chan->rb); in atmel_tcb_pwm_resume()
515 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, RC), chan->rc); in atmel_tcb_pwm_resume()
517 if (chan->enabled) in atmel_tcb_pwm_resume()
518 regmap_write(tcbpwm->regmap, in atmel_tcb_pwm_resume()
531 .name = "atmel-tcb-pwm",