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

1 // SPDX-License-Identifier: GPL-2.0-only
76 struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_set_polarity()
78 tcbpwm->polarity = polarity; in atmel_tcb_pwm_set_polarity()
91 tcbpwm = devm_kzalloc(chip->dev, sizeof(*tcbpwm), GFP_KERNEL); in atmel_tcb_pwm_request()
93 return -ENOMEM; in atmel_tcb_pwm_request()
95 ret = clk_prepare_enable(tcbpwmc->clk); in atmel_tcb_pwm_request()
97 devm_kfree(chip->dev, tcbpwm); in atmel_tcb_pwm_request()
101 tcbpwm->polarity = PWM_POLARITY_NORMAL; in atmel_tcb_pwm_request()
102 tcbpwm->duty = 0; in atmel_tcb_pwm_request()
103 tcbpwm->period = 0; in atmel_tcb_pwm_request()
104 tcbpwm->div = 0; in atmel_tcb_pwm_request()
106 spin_lock(&tcbpwmc->lock); in atmel_tcb_pwm_request()
107 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); in atmel_tcb_pwm_request()
113 if (pwm->hwpwm == 0) in atmel_tcb_pwm_request()
114 regmap_read(tcbpwmc->regmap, in atmel_tcb_pwm_request()
115 ATMEL_TC_REG(tcbpwmc->channel, RA), in atmel_tcb_pwm_request()
116 &tcbpwm->duty); in atmel_tcb_pwm_request()
118 regmap_read(tcbpwmc->regmap, in atmel_tcb_pwm_request()
119 ATMEL_TC_REG(tcbpwmc->channel, RB), in atmel_tcb_pwm_request()
120 &tcbpwm->duty); in atmel_tcb_pwm_request()
122 tcbpwm->div = cmr & ATMEL_TC_TCCLKS; in atmel_tcb_pwm_request()
123 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, RC), in atmel_tcb_pwm_request()
124 &tcbpwm->period); in atmel_tcb_pwm_request()
131 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); in atmel_tcb_pwm_request()
132 spin_unlock(&tcbpwmc->lock); in atmel_tcb_pwm_request()
134 tcbpwmc->pwms[pwm->hwpwm] = tcbpwm; in atmel_tcb_pwm_request()
142 struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_free()
144 clk_disable_unprepare(tcbpwmc->clk); in atmel_tcb_pwm_free()
145 tcbpwmc->pwms[pwm->hwpwm] = NULL; in atmel_tcb_pwm_free()
146 devm_kfree(chip->dev, tcbpwm); in atmel_tcb_pwm_free()
152 struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_disable()
154 enum pwm_polarity polarity = tcbpwm->polarity; in atmel_tcb_pwm_disable()
159 * - set output to high if PWM_POLARITY_INVERSED in atmel_tcb_pwm_disable()
160 * - set output to low if PWM_POLARITY_NORMAL in atmel_tcb_pwm_disable()
164 if (tcbpwm->duty == 0) in atmel_tcb_pwm_disable()
167 spin_lock(&tcbpwmc->lock); in atmel_tcb_pwm_disable()
168 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); in atmel_tcb_pwm_disable()
171 if (pwm->hwpwm == 0) { in atmel_tcb_pwm_disable()
185 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); in atmel_tcb_pwm_disable()
192 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_disable()
193 ATMEL_TC_REG(tcbpwmc->channel, CCR), in atmel_tcb_pwm_disable()
195 tcbpwmc->bkup.enabled = 1; in atmel_tcb_pwm_disable()
197 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_disable()
198 ATMEL_TC_REG(tcbpwmc->channel, CCR), in atmel_tcb_pwm_disable()
200 tcbpwmc->bkup.enabled = 0; in atmel_tcb_pwm_disable()
203 spin_unlock(&tcbpwmc->lock); in atmel_tcb_pwm_disable()
209 struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_enable()
211 enum pwm_polarity polarity = tcbpwm->polarity; in atmel_tcb_pwm_enable()
216 * - set output to high if PWM_POLARITY_INVERSED in atmel_tcb_pwm_enable()
217 * - set output to low if PWM_POLARITY_NORMAL in atmel_tcb_pwm_enable()
221 if (tcbpwm->duty == 0) in atmel_tcb_pwm_enable()
224 spin_lock(&tcbpwmc->lock); in atmel_tcb_pwm_enable()
225 regmap_read(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), &cmr); in atmel_tcb_pwm_enable()
230 if (pwm->hwpwm == 0) { in atmel_tcb_pwm_enable()
252 if (tcbpwm->duty != tcbpwm->period && tcbpwm->duty > 0) { in atmel_tcb_pwm_enable()
253 if (pwm->hwpwm == 0) { in atmel_tcb_pwm_enable()
266 cmr |= (tcbpwm->div & ATMEL_TC_TCCLKS); in atmel_tcb_pwm_enable()
268 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr); in atmel_tcb_pwm_enable()
270 if (pwm->hwpwm == 0) in atmel_tcb_pwm_enable()
271 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_enable()
272 ATMEL_TC_REG(tcbpwmc->channel, RA), in atmel_tcb_pwm_enable()
273 tcbpwm->duty); in atmel_tcb_pwm_enable()
275 regmap_write(tcbpwmc->regmap, in atmel_tcb_pwm_enable()
276 ATMEL_TC_REG(tcbpwmc->channel, RB), in atmel_tcb_pwm_enable()
277 tcbpwm->duty); in atmel_tcb_pwm_enable()
279 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, RC), in atmel_tcb_pwm_enable()
280 tcbpwm->period); in atmel_tcb_pwm_enable()
283 regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CCR), in atmel_tcb_pwm_enable()
285 tcbpwmc->bkup.enabled = 1; in atmel_tcb_pwm_enable()
286 spin_unlock(&tcbpwmc->lock); in atmel_tcb_pwm_enable()
294 struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm]; in atmel_tcb_pwm_config()
300 unsigned rate = clk_get_rate(tcbpwmc->clk); in atmel_tcb_pwm_config()
309 if (tcbpwmc->gclk) in atmel_tcb_pwm_config()
317 max = min << tcbpwmc->width; in atmel_tcb_pwm_config()
328 rate = clk_get_rate(tcbpwmc->slow_clk); in atmel_tcb_pwm_config()
330 max = min << tcbpwmc->width; in atmel_tcb_pwm_config()
334 return -ERANGE; in atmel_tcb_pwm_config()
340 if (pwm->hwpwm == 0) in atmel_tcb_pwm_config()
341 atcbpwm = tcbpwmc->pwms[1]; in atmel_tcb_pwm_config()
343 atcbpwm = tcbpwmc->pwms[0]; in atmel_tcb_pwm_config()
346 * PWM devices provided by the TCB driver are grouped by 2. in atmel_tcb_pwm_config()
353 if ((atcbpwm && atcbpwm->duty > 0 && in atmel_tcb_pwm_config()
354 atcbpwm->duty != atcbpwm->period) && in atmel_tcb_pwm_config()
355 (atcbpwm->div != i || atcbpwm->period != period)) { in atmel_tcb_pwm_config()
356 dev_err(chip->dev, in atmel_tcb_pwm_config()
358 return -EINVAL; in atmel_tcb_pwm_config()
361 tcbpwm->period = period; in atmel_tcb_pwm_config()
362 tcbpwm->div = i; in atmel_tcb_pwm_config()
363 tcbpwm->duty = duty; in atmel_tcb_pwm_config()
375 atmel_tcb_pwm_set_polarity(chip, pwm, state->polarity); in atmel_tcb_pwm_apply()
377 if (!state->enabled) { in atmel_tcb_pwm_apply()
382 period = state->period < INT_MAX ? state->period : INT_MAX; in atmel_tcb_pwm_apply()
383 duty_cycle = state->duty_cycle < INT_MAX ? state->duty_cycle : INT_MAX; in atmel_tcb_pwm_apply()
413 { .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, },
414 { .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, },
415 { .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, },
424 struct device_node *np = pdev->dev.of_node; in atmel_tcb_pwm_probe()
434 dev_err(&pdev->dev, in atmel_tcb_pwm_probe()
440 regmap = syscon_node_to_regmap(np->parent); in atmel_tcb_pwm_probe()
444 slow_clk = of_clk_get_by_name(np->parent, "slow_clk"); in atmel_tcb_pwm_probe()
449 clk = of_clk_get_by_name(np->parent, clk_name); in atmel_tcb_pwm_probe()
451 clk = of_clk_get_by_name(np->parent, "t0_clk"); in atmel_tcb_pwm_probe()
455 match = of_match_node(atmel_tcb_of_match, np->parent); in atmel_tcb_pwm_probe()
456 config = match->data; in atmel_tcb_pwm_probe()
458 if (config->has_gclk) { in atmel_tcb_pwm_probe()
459 gclk = of_clk_get_by_name(np->parent, "gclk"); in atmel_tcb_pwm_probe()
464 tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); in atmel_tcb_pwm_probe()
466 err = -ENOMEM; in atmel_tcb_pwm_probe()
470 tcbpwm->chip.dev = &pdev->dev; in atmel_tcb_pwm_probe()
471 tcbpwm->chip.ops = &atmel_tcb_pwm_ops; in atmel_tcb_pwm_probe()
472 tcbpwm->chip.npwm = NPWM; in atmel_tcb_pwm_probe()
473 tcbpwm->channel = channel; in atmel_tcb_pwm_probe()
474 tcbpwm->regmap = regmap; in atmel_tcb_pwm_probe()
475 tcbpwm->clk = clk; in atmel_tcb_pwm_probe()
476 tcbpwm->gclk = gclk; in atmel_tcb_pwm_probe()
477 tcbpwm->slow_clk = slow_clk; in atmel_tcb_pwm_probe()
478 tcbpwm->width = config->counter_width; in atmel_tcb_pwm_probe()
484 spin_lock_init(&tcbpwm->lock); in atmel_tcb_pwm_probe()
486 err = pwmchip_add(&tcbpwm->chip); in atmel_tcb_pwm_probe()
495 clk_disable_unprepare(tcbpwm->slow_clk); in atmel_tcb_pwm_probe()
507 pwmchip_remove(&tcbpwm->chip); in atmel_tcb_pwm_remove()
509 clk_disable_unprepare(tcbpwm->slow_clk); in atmel_tcb_pwm_remove()
510 clk_put(tcbpwm->slow_clk); in atmel_tcb_pwm_remove()
511 clk_put(tcbpwm->clk); in atmel_tcb_pwm_remove()
517 { .compatible = "atmel,tcb-pwm", },
526 struct atmel_tcb_channel *chan = &tcbpwm->bkup; in atmel_tcb_pwm_suspend()
527 unsigned int channel = tcbpwm->channel; in atmel_tcb_pwm_suspend()
529 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, CMR), &chan->cmr); in atmel_tcb_pwm_suspend()
530 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, RA), &chan->ra); in atmel_tcb_pwm_suspend()
531 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, RB), &chan->rb); in atmel_tcb_pwm_suspend()
532 regmap_read(tcbpwm->regmap, ATMEL_TC_REG(channel, RC), &chan->rc); in atmel_tcb_pwm_suspend()
540 struct atmel_tcb_channel *chan = &tcbpwm->bkup; in atmel_tcb_pwm_resume()
541 unsigned int channel = tcbpwm->channel; in atmel_tcb_pwm_resume()
543 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, CMR), chan->cmr); in atmel_tcb_pwm_resume()
544 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, RA), chan->ra); in atmel_tcb_pwm_resume()
545 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, RB), chan->rb); in atmel_tcb_pwm_resume()
546 regmap_write(tcbpwm->regmap, ATMEL_TC_REG(channel, RC), chan->rc); in atmel_tcb_pwm_resume()
548 if (chan->enabled) in atmel_tcb_pwm_resume()
549 regmap_write(tcbpwm->regmap, in atmel_tcb_pwm_resume()
562 .name = "atmel-tcb-pwm",