static void bfin_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: { set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | \ TIMER_PERIOD_CNT | TIMER_MODE_PWM); set_gptimer_period(TIMER0_id, get_sclk() / HZ); set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); enable_gptimers(TIMER0bit); break; } case CLOCK_EVT_MODE_ONESHOT: disable_gptimers(TIMER0bit); set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); set_gptimer_period(TIMER0_id, 0); break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: disable_gptimers(TIMER0bit); break; case CLOCK_EVT_MODE_RESUME: break; } }
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) { unsigned long period, duty; unsigned long long val; if (duty_ns < 0 || duty_ns > period_ns) return -EINVAL; val = (unsigned long long)get_sclk() * period_ns; do_div(val, NSEC_PER_SEC); period = val; val = (unsigned long long)period * duty_ns; do_div(val, period_ns); duty = period - val; if (duty >= period) duty = period - 1; set_gptimer_config(pwm->id, TIMER_MODE_PWM | TIMER_PERIOD_CNT); set_gptimer_pwidth(pwm->id, duty); set_gptimer_period(pwm->id, period); return 0; }
static int __init gptimer_example_init(void) { int ret; ret = peripheral_request(P_TMR5, DRIVER_NAME); if (ret) { printk(KERN_NOTICE DRIVER_NAME ": peripheral request failed\n"); return ret; } ret = request_irq(IRQ_TIMER5, gptimer_example_irq, IRQF_SHARED, DRIVER_NAME, &data); if (ret) { printk(KERN_NOTICE DRIVER_NAME ": IRQ request failed\n"); peripheral_free(P_TMR5); return ret; } set_gptimer_config(TIMER5_id, WDTH_CAP | PULSE_HI | PERIOD_CNT | IRQ_ENA); enable_gptimers(TIMER5bit); return 0; }
void __init setup_gptimer0(void) { disable_gptimers(TIMER0bit); set_gptimer_config(TIMER0_id, \ TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); set_gptimer_period(TIMER0_id, -1); set_gptimer_pwidth(TIMER0_id, -2); SSYNC(); enable_gptimers(TIMER0bit); }
void __init setup_system_timer0(void) { /* Power down the core timer, just to play safe. */ bfin_write_TCNTL(0); disable_gptimers(TIMER0bit); set_gptimer_status(0, TIMER_STATUS_TRUN0); while (get_gptimer_status(0) & TIMER_STATUS_TRUN0) udelay(10); set_gptimer_config(0, 0x59); /* IRQ enable, periodic, PWM_OUT, SCLKed, OUT PAD disabled */ set_gptimer_period(TIMER0_id, get_sclk() / HZ); set_gptimer_pwidth(TIMER0_id, 1); SSYNC(); enable_gptimers(TIMER0bit); }
static int bfin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct bfin_pwm *priv = pwm_get_chip_data(pwm); unsigned long period, duty; unsigned long long val; val = (unsigned long long)get_sclk() * period_ns; do_div(val, NSEC_PER_SEC); period = val; val = (unsigned long long)period * duty_ns; do_div(val, period_ns); duty = period - val; if (duty >= period) duty = period - 1; set_gptimer_config(priv->pin, TIMER_MODE_PWM | TIMER_PERIOD_CNT); set_gptimer_pwidth(priv->pin, duty); set_gptimer_period(priv->pin, period); return 0; }
static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev) { struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data; struct bfin_tmr_state *st; unsigned int config; int ret; st = kzalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) { ret = -ENOMEM; goto out; } st->irq = platform_get_irq(pdev, 0); if (!st->irq) { dev_err(&pdev->dev, "No IRQs specified"); ret = -ENODEV; goto out1; } ret = iio_bfin_tmr_get_number(st->irq); if (ret < 0) goto out1; st->timer_num = ret; st->t = &iio_bfin_timer_code[st->timer_num]; st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num); if (!st->trig) { ret = -ENOMEM; goto out1; } st->trig->private_data = st; st->trig->ops = &iio_bfin_tmr_trigger_ops; st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups; ret = iio_trigger_register(st->trig); if (ret) goto out2; ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr, 0, st->trig->name, st); if (ret) { dev_err(&pdev->dev, "request IRQ-%d failed", st->irq); goto out4; } config = PWM_OUT | PERIOD_CNT | IRQ_ENA; if (pdata && pdata->output_enable) { unsigned long long val; st->output_enable = true; ret = peripheral_request(st->t->pin, st->trig->name); if (ret) goto out_free_irq; val = (unsigned long long)get_sclk() * pdata->duty_ns; do_div(val, NSEC_PER_SEC); st->duty = val; /** * The interrupt will be generated at the end of the period, * since we want the interrupt to be generated at end of the * pulse we invert both polarity and duty cycle, so that the * pulse will be generated directly before the interrupt. */ if (pdata->active_low) config |= PULSE_HI; } else { st->duty = 1; config |= OUT_DIS; } set_gptimer_config(st->t->id, config); dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d", st->timer_num, st->irq); platform_set_drvdata(pdev, st); return 0; out_free_irq: free_irq(st->irq, st); out4: iio_trigger_unregister(st->trig); out2: iio_trigger_put(st->trig); out1: kfree(st); out: return ret; }
static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) { struct bfin_tmr_state *st; int ret; st = kzalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) { ret = -ENOMEM; goto out; } st->irq = platform_get_irq(pdev, 0); if (!st->irq) { dev_err(&pdev->dev, "No IRQs specified"); ret = -ENODEV; goto out1; } ret = iio_bfin_tmr_get_number(st->irq); if (ret < 0) goto out1; st->timer_num = ret; st->t = &iio_bfin_timer_code[st->timer_num]; st->trig = iio_allocate_trigger("bfintmr%d", st->timer_num); if (!st->trig) { ret = -ENOMEM; goto out1; } st->trig->private_data = st; st->trig->ops = &iio_bfin_tmr_trigger_ops; st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups; ret = iio_trigger_register(st->trig); if (ret) goto out2; ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr, 0, st->trig->name, st); if (ret) { dev_err(&pdev->dev, "request IRQ-%d failed", st->irq); goto out4; } set_gptimer_config(st->t->id, OUT_DIS | PWM_OUT | PERIOD_CNT | IRQ_ENA); dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d", st->timer_num, st->irq); platform_set_drvdata(pdev, st); return 0; out4: iio_trigger_unregister(st->trig); out2: iio_put_trigger(st->trig); out1: kfree(st); out: return ret; }