• Home
  • Raw
  • Download

Lines Matching +full:- +full:pwm

2  * R-Mobile TPU PWM driver
26 #include <linux/pwm.h>
71 TPU_PIN_PWM, /* Pin is driven by PWM */
100 static void tpu_pwm_write(struct tpu_pwm_device *pwm, int reg_nr, u16 value) in tpu_pwm_write() argument
102 void __iomem *base = pwm->tpu->base + TPU_CHANNEL_OFFSET in tpu_pwm_write()
103 + pwm->channel * TPU_CHANNEL_SIZE; in tpu_pwm_write()
108 static void tpu_pwm_set_pin(struct tpu_pwm_device *pwm, in tpu_pwm_set_pin() argument
111 static const char * const states[] = { "inactive", "PWM", "active" }; in tpu_pwm_set_pin()
113 dev_dbg(&pwm->tpu->pdev->dev, "%u: configuring pin as %s\n", in tpu_pwm_set_pin()
114 pwm->channel, states[state]); in tpu_pwm_set_pin()
118 tpu_pwm_write(pwm, TPU_TIORn, in tpu_pwm_set_pin()
119 pwm->polarity == PWM_POLARITY_INVERSED ? in tpu_pwm_set_pin()
123 tpu_pwm_write(pwm, TPU_TIORn, in tpu_pwm_set_pin()
124 pwm->polarity == PWM_POLARITY_INVERSED ? in tpu_pwm_set_pin()
128 tpu_pwm_write(pwm, TPU_TIORn, in tpu_pwm_set_pin()
129 pwm->polarity == PWM_POLARITY_INVERSED ? in tpu_pwm_set_pin()
135 static void tpu_pwm_start_stop(struct tpu_pwm_device *pwm, int start) in tpu_pwm_start_stop() argument
140 spin_lock_irqsave(&pwm->tpu->lock, flags); in tpu_pwm_start_stop()
141 value = ioread16(pwm->tpu->base + TPU_TSTR); in tpu_pwm_start_stop()
144 value |= 1 << pwm->channel; in tpu_pwm_start_stop()
146 value &= ~(1 << pwm->channel); in tpu_pwm_start_stop()
148 iowrite16(value, pwm->tpu->base + TPU_TSTR); in tpu_pwm_start_stop()
149 spin_unlock_irqrestore(&pwm->tpu->lock, flags); in tpu_pwm_start_stop()
152 static int tpu_pwm_timer_start(struct tpu_pwm_device *pwm) in tpu_pwm_timer_start() argument
156 if (!pwm->timer_on) { in tpu_pwm_timer_start()
158 pm_runtime_get_sync(&pwm->tpu->pdev->dev); in tpu_pwm_timer_start()
159 ret = clk_prepare_enable(pwm->tpu->clk); in tpu_pwm_timer_start()
161 dev_err(&pwm->tpu->pdev->dev, "cannot enable clock\n"); in tpu_pwm_timer_start()
164 pwm->timer_on = true; in tpu_pwm_timer_start()
172 tpu_pwm_set_pin(pwm, TPU_PIN_INACTIVE); in tpu_pwm_timer_start()
173 tpu_pwm_start_stop(pwm, false); in tpu_pwm_timer_start()
176 * - Clear TCNT on TGRB match in tpu_pwm_timer_start()
177 * - Count on rising edge in tpu_pwm_timer_start()
178 * - Set prescaler in tpu_pwm_timer_start()
179 * - Output 0 until TGRA, output 1 until TGRB (active low polarity) in tpu_pwm_timer_start()
180 * - Output 1 until TGRA, output 0 until TGRB (active high polarity in tpu_pwm_timer_start()
181 * - PWM mode in tpu_pwm_timer_start()
183 tpu_pwm_write(pwm, TPU_TCRn, TPU_TCR_CCLR_TGRB | TPU_TCR_CKEG_RISING | in tpu_pwm_timer_start()
184 pwm->prescaler); in tpu_pwm_timer_start()
185 tpu_pwm_write(pwm, TPU_TMDRn, TPU_TMDR_MD_PWM); in tpu_pwm_timer_start()
186 tpu_pwm_set_pin(pwm, TPU_PIN_PWM); in tpu_pwm_timer_start()
187 tpu_pwm_write(pwm, TPU_TGRAn, pwm->duty); in tpu_pwm_timer_start()
188 tpu_pwm_write(pwm, TPU_TGRBn, pwm->period); in tpu_pwm_timer_start()
190 dev_dbg(&pwm->tpu->pdev->dev, "%u: TGRA 0x%04x TGRB 0x%04x\n", in tpu_pwm_timer_start()
191 pwm->channel, pwm->duty, pwm->period); in tpu_pwm_timer_start()
194 tpu_pwm_start_stop(pwm, true); in tpu_pwm_timer_start()
199 static void tpu_pwm_timer_stop(struct tpu_pwm_device *pwm) in tpu_pwm_timer_stop() argument
201 if (!pwm->timer_on) in tpu_pwm_timer_stop()
205 tpu_pwm_start_stop(pwm, false); in tpu_pwm_timer_stop()
208 clk_disable_unprepare(pwm->tpu->clk); in tpu_pwm_timer_stop()
209 pm_runtime_put(&pwm->tpu->pdev->dev); in tpu_pwm_timer_stop()
211 pwm->timer_on = false; in tpu_pwm_timer_stop()
214 /* -----------------------------------------------------------------------------
215 * PWM API
221 struct tpu_pwm_device *pwm; in tpu_pwm_request() local
223 if (_pwm->hwpwm >= TPU_CHANNEL_MAX) in tpu_pwm_request()
224 return -EINVAL; in tpu_pwm_request()
226 pwm = kzalloc(sizeof(*pwm), GFP_KERNEL); in tpu_pwm_request()
227 if (pwm == NULL) in tpu_pwm_request()
228 return -ENOMEM; in tpu_pwm_request()
230 pwm->tpu = tpu; in tpu_pwm_request()
231 pwm->channel = _pwm->hwpwm; in tpu_pwm_request()
232 pwm->polarity = PWM_POLARITY_NORMAL; in tpu_pwm_request()
233 pwm->prescaler = 0; in tpu_pwm_request()
234 pwm->period = 0; in tpu_pwm_request()
235 pwm->duty = 0; in tpu_pwm_request()
237 pwm->timer_on = false; in tpu_pwm_request()
239 pwm_set_chip_data(_pwm, pwm); in tpu_pwm_request()
246 struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm); in tpu_pwm_free() local
248 tpu_pwm_timer_stop(pwm); in tpu_pwm_free()
249 kfree(pwm); in tpu_pwm_free()
256 struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm); in tpu_pwm_config() local
269 clk_rate = clk_get_rate(tpu->clk); in tpu_pwm_config()
279 dev_err(&tpu->pdev->dev, "clock rate mismatch\n"); in tpu_pwm_config()
280 return -ENOTSUPP; in tpu_pwm_config()
287 return -EINVAL; in tpu_pwm_config()
292 dev_dbg(&tpu->pdev->dev, in tpu_pwm_config()
296 if (pwm->prescaler == prescaler && pwm->period == period) in tpu_pwm_config()
299 pwm->prescaler = prescaler; in tpu_pwm_config()
300 pwm->period = period; in tpu_pwm_config()
301 pwm->duty = duty; in tpu_pwm_config()
307 if (duty_only && pwm->timer_on) { in tpu_pwm_config()
313 tpu_pwm_write(pwm, TPU_TGRAn, pwm->duty); in tpu_pwm_config()
314 dev_dbg(&tpu->pdev->dev, "%u: TGRA 0x%04x\n", pwm->channel, in tpu_pwm_config()
315 pwm->duty); in tpu_pwm_config()
318 ret = tpu_pwm_timer_start(pwm); in tpu_pwm_config()
328 tpu_pwm_set_pin(pwm, duty ? TPU_PIN_ACTIVE : TPU_PIN_INACTIVE); in tpu_pwm_config()
329 tpu_pwm_timer_stop(pwm); in tpu_pwm_config()
338 struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm); in tpu_pwm_set_polarity() local
340 pwm->polarity = polarity; in tpu_pwm_set_polarity()
347 struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm); in tpu_pwm_enable() local
350 ret = tpu_pwm_timer_start(pwm); in tpu_pwm_enable()
358 if (pwm->duty == 0 || pwm->duty == pwm->period) { in tpu_pwm_enable()
359 tpu_pwm_set_pin(pwm, pwm->duty ? in tpu_pwm_enable()
361 tpu_pwm_timer_stop(pwm); in tpu_pwm_enable()
369 struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm); in tpu_pwm_disable() local
372 tpu_pwm_timer_start(pwm); in tpu_pwm_disable()
373 tpu_pwm_set_pin(pwm, TPU_PIN_INACTIVE); in tpu_pwm_disable()
374 tpu_pwm_timer_stop(pwm); in tpu_pwm_disable()
387 /* -----------------------------------------------------------------------------
397 tpu = devm_kzalloc(&pdev->dev, sizeof(*tpu), GFP_KERNEL); in tpu_probe()
399 return -ENOMEM; in tpu_probe()
401 spin_lock_init(&tpu->lock); in tpu_probe()
402 tpu->pdev = pdev; in tpu_probe()
406 tpu->base = devm_ioremap_resource(&pdev->dev, res); in tpu_probe()
407 if (IS_ERR(tpu->base)) in tpu_probe()
408 return PTR_ERR(tpu->base); in tpu_probe()
410 tpu->clk = devm_clk_get(&pdev->dev, NULL); in tpu_probe()
411 if (IS_ERR(tpu->clk)) { in tpu_probe()
412 dev_err(&pdev->dev, "cannot get clock\n"); in tpu_probe()
413 return PTR_ERR(tpu->clk); in tpu_probe()
419 tpu->chip.dev = &pdev->dev; in tpu_probe()
420 tpu->chip.ops = &tpu_pwm_ops; in tpu_probe()
421 tpu->chip.of_xlate = of_pwm_xlate_with_flags; in tpu_probe()
422 tpu->chip.of_pwm_n_cells = 3; in tpu_probe()
423 tpu->chip.base = -1; in tpu_probe()
424 tpu->chip.npwm = TPU_CHANNEL_MAX; in tpu_probe()
426 pm_runtime_enable(&pdev->dev); in tpu_probe()
428 ret = pwmchip_add(&tpu->chip); in tpu_probe()
430 dev_err(&pdev->dev, "failed to register PWM chip\n"); in tpu_probe()
431 pm_runtime_disable(&pdev->dev); in tpu_probe()
435 dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id); in tpu_probe()
445 ret = pwmchip_remove(&tpu->chip); in tpu_remove()
447 pm_runtime_disable(&pdev->dev); in tpu_remove()
454 { .compatible = "renesas,tpu-r8a73a4", },
455 { .compatible = "renesas,tpu-r8a7740", },
456 { .compatible = "renesas,tpu-r8a7790", },
468 .name = "renesas-tpu-pwm",
476 MODULE_DESCRIPTION("Renesas TPU PWM Driver");
478 MODULE_ALIAS("platform:renesas-tpu-pwm");