Exemplo n.º 1
0
static void pwm_config_ns_to_ticks(struct pwm_device *p, struct pwm_config *c)
{
    if (test_bit(PWM_CONFIG_PERIOD_NS, &c->config_mask)) {
        c->period_ticks = pwm_ns_to_ticks(p, c->period_ns);
        clear_bit(PWM_CONFIG_PERIOD_NS, &c->config_mask);
        set_bit(PWM_CONFIG_PERIOD_TICKS, &c->config_mask);
    }

    if (test_bit(PWM_CONFIG_DUTY_NS, &c->config_mask)) {
        c->duty_ticks = pwm_ns_to_ticks(p, c->duty_ns);
        clear_bit(PWM_CONFIG_DUTY_NS, &c->config_mask);
        set_bit(PWM_CONFIG_DUTY_TICKS, &c->config_mask);
    }
}
Exemplo n.º 2
0
int pwm_set_period_ns(struct pwm_device *p, unsigned long period_ns)
{
    struct pwm_config c = {
        .config_mask = BIT(PWM_CONFIG_PERIOD_TICKS),
        .period_ticks = pwm_ns_to_ticks(p, period_ns),
    };

    spin_lock(&p->pwm_lock);
    p->period_ns = period_ns;
    spin_unlock(&p->pwm_lock);
    return pwm_config(p, &c);
}
EXPORT_SYMBOL(pwm_set_period_ns);

unsigned long pwm_get_period_ns(struct pwm_device *p)
{
    return pwm_ticks_to_ns(p, p->period_ticks);
}
EXPORT_SYMBOL(pwm_get_period_ns);

int pwm_set_frequency(struct pwm_device *p, unsigned long freq)
{
    struct pwm_config c;

    if (!freq)
        return -EINVAL;

    c.config_mask = BIT(PWM_CONFIG_PERIOD_TICKS),
      c.period_ticks = pwm_ns_to_ticks(p, (NSEC_PER_SEC / freq)),
        spin_lock(&p->pwm_lock);
    p->period_ns = NSEC_PER_SEC / freq;
    spin_unlock(&p->pwm_lock);
    return pwm_config(p, &c);
}
EXPORT_SYMBOL(pwm_set_frequency);

unsigned long pwm_get_frequency(struct pwm_device *p)
{
    unsigned long period_ns;

    period_ns = pwm_ticks_to_ns(p, p->period_ticks);

    if (!period_ns) {
        pr_debug("%s: frequency is zero\n", dev_name(p->dev));
        return 0;
    }

    return	NSEC_PER_SEC / period_ns;
}
Exemplo n.º 3
0
int ehrpwm_db_set_delay(struct pwm_device *p, unsigned char edge,
		enum config_mask cfgmask, unsigned long delay)
{
	struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
	unsigned long delay_ticks;
	unsigned char offset = 0;

	if (!ehrpwm)
		return -EINVAL;

	if (edge == RISING_EDGE_DELAY)
		offset = DBRED;
	else if (edge == FALLING_EDGE_DELAY)
		offset = DBFED;
	else
		return -EINVAL;

	if (cfgmask == CONFIG_TICKS) {
		delay = delay / ehrpwm->prescale_val;
		if (delay > 0x3ff)
			return -EINVAL;
		ehrpwm_write(ehrpwm, offset, delay);
	} else if (cfgmask == CONFIG_NS) {
		delay_ticks = pwm_ns_to_ticks(p, delay);
		delay_ticks = delay_ticks / ehrpwm->prescale_val;
		if (delay_ticks > 0x3ff) {
			ehrpwm_db_get_max_delay(p, CONFIG_NS, &delay_ticks);
			dev_dbg(p->dev, "%s: Expected delay cannot be"
			" attained setting the maximum possible delay of"
			" %lu ns", __func__, delay_ticks);
			delay_ticks = 0x3ff;
		}
		debug("\n delay ticks is %lu", delay_ticks);
		ehrpwm_write(ehrpwm, offset, delay_ticks);
	} else {
		return -EINVAL;
	}

	return 0;
}
Exemplo n.º 4
0
static int ehrpwm_probe(struct platform_device *pdev)
{
	struct ehrpwm_pwm *ehrpwm = NULL;
	struct resource *r;
	int ret = 0;
	int chan = 0;
	struct pwmss_platform_data *pdata = (&pdev->dev)->platform_data;
	int ch_mask = 0;
	int val;
	char con_id[PWM_CON_ID_STRING_LENGTH] = "epwmss";

	ehrpwm = kzalloc(sizeof(*ehrpwm), GFP_KERNEL);
	if (!ehrpwm) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		ret = -ENOMEM;
		goto err_mem_failure;
	}

	ehrpwm->version = pdata->version;

	if (ehrpwm->version == PWM_VERSION_1) {
		sprintf(con_id, "%s%d_%s", con_id, pdev->id, "fck");
		ehrpwm->clk = clk_get(&pdev->dev, con_id);
	} else
		ehrpwm->clk = clk_get(&pdev->dev, "ehrpwm");

	pm_runtime_enable(&pdev->dev);
	ehrpwm->dev = &pdev->dev;
	if (IS_ERR(ehrpwm->clk)) {
		ret = PTR_ERR(ehrpwm->clk);
		goto err_clock_failure;
	}

	if (ehrpwm->version == PWM_VERSION_1) {
		r = platform_get_resource(pdev, IORESOURCE_MEM, 0);

		if (!r) {
			dev_err(&pdev->dev, "no memory resource defined\n");
			ret = -ENOMEM;
			goto err_resource_mem_failure;
		}

		ehrpwm->config_mem_base = ioremap(r->start, resource_size(r));

		if (!ehrpwm->config_mem_base) {

			dev_err(&pdev->dev, "failed to ioremap() registers\n");
			ret = -ENODEV;
			goto err_free_mem_config;
		}

		pm_runtime_get_sync(ehrpwm->dev);
		val = readw(ehrpwm->config_mem_base + PWMSS_CLKCONFIG);
		val |= BIT(EPWM_CLK_EN);
		writew(val, ehrpwm->config_mem_base + PWMSS_CLKCONFIG);
		pm_runtime_put_sync(ehrpwm->dev);
	} else
		ch_mask = pdata->channel_mask;

	spin_lock_init(&ehrpwm->lock);
	ehrpwm->ops.config = ehrpwm_pwm_config;
	ehrpwm->ops.request = ehrpwm_pwm_request;
	ehrpwm->ops.freq_transition_notifier_cb = ehrpwm_freq_transition_cb;
	ehrpwm->prescale_val = 1;

	if (ehrpwm->version == PWM_VERSION_1)
		r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	else
		r = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!r) {
		dev_err(&pdev->dev, "no memory resource defined\n");
		ret = -ENODEV;
		goto err_resource_mem2_failiure;
	}

	r = request_mem_region(r->start, resource_size(r), pdev->name);
	if (!r) {
		dev_err(&pdev->dev, "failed to request memory resource\n");
		ret = -EBUSY;
		goto err_request_mem2_failure;
	}

	ehrpwm->mmio_base = ioremap(r->start, resource_size(r));
	if (!ehrpwm->mmio_base) {
		dev_err(&pdev->dev, "failed to ioremap() registers\n");
		ret = -ENODEV;
		goto err_free_mem2;
	}

	ehrpwm->irq[0] = platform_get_irq(pdev, 0);
	if (ehrpwm->irq[0] == -ENXIO) {
		dev_err(&pdev->dev, "No IRQ resource\n");
		ret = -ENXIO;
		goto err_free_io;
	}

	ret = request_irq(ehrpwm->irq[0], ehrpwm_trip_zone_irq_handler,
				0, "ehrpwmTZ", ehrpwm);
	if (ret)
		goto err_free_io;

	ehrpwm->irq[1] = platform_get_irq(pdev, 1);
	if (ehrpwm->irq[1] == -ENXIO) {
		dev_err(&pdev->dev, "No IRQ resource\n");
		ret = -ENXIO;
		goto err_request_irq;
	}

	ret = request_irq(ehrpwm->irq[1], ehrpwm_event_irq_handler,
				0, "ehrpwm_evt", ehrpwm);
	if (ret)
		goto err_request_irq;

	for (chan = 0; chan < NCHAN; chan++) {
		ehrpwm->pwm[chan].ops = &ehrpwm->ops;
		pwm_set_drvdata(&ehrpwm->pwm[chan], ehrpwm);
		ehrpwm->pwm[chan].tick_hz = clk_get_rate(ehrpwm->clk);

		if (pdata->chan_attrib[chan].max_freq) {
			int period_ns = NSEC_PER_SEC
				/ pdata->chan_attrib[chan].max_freq;

			ehrpwm->pwm[chan].max_period_ticks =
				pwm_ns_to_ticks(&ehrpwm->pwm[chan], period_ns);
		}

		if (!(ehrpwm->version == PWM_VERSION_1)) {
			if (!(ch_mask & (0x1 << chan)))
				continue;
		}

		ret =  pwm_register(&ehrpwm->pwm[chan], &pdev->dev, chan);
		if (ret)
			goto err_pwm_register;
	}

		platform_set_drvdata(pdev, ehrpwm);
	return 0;

err_pwm_register:
	for (chan = 0; chan < NCHAN; chan++) {
		if (pwm_is_registered(&ehrpwm->pwm[chan]))
			pwm_unregister(&ehrpwm->pwm[chan]);
	}

err_request_irq:
	if (ehrpwm->irq[0] != -ENXIO)
		free_irq(ehrpwm->irq[0], ehrpwm);
err_free_io:
	iounmap(ehrpwm->mmio_base);
err_free_mem2:
	release_mem_region(r->start, resource_size(r));
err_request_mem2_failure:
err_resource_mem2_failiure:
	if (ehrpwm->version == PWM_VERSION_1) {
		iounmap(ehrpwm->config_mem_base);
		ehrpwm->config_mem_base = NULL;
	}
err_free_mem_config:
err_resource_mem_failure:
	clk_put(ehrpwm->clk);
	pm_runtime_disable(ehrpwm->dev);
err_clock_failure:
	kfree(ehrpwm);
err_mem_failure:
	return ret;
}