示例#1
0
文件: up_pwm.c 项目: alexlotw/nuttx
/*
 * Caution:
 *   For TSB, PWM1 is pinshared with GPIO9, and their use is therefore exclusive.
 *   Applications intending to control PWM1 must ensure that the PINSHARE register is
 *   configured appropriately.
 */
int pwm_devinit(void)
{
    static int pwm0_initialized = 0;
    static int pwm1_initialized = 0;
    struct pwm_lowerhalf_s *pwm;
    int ret;

    /* Have we already initialized PWM0? */
    if (!pwm0_initialized) {
        /* Call tsb_pwminitialize() to get an instance of the PWM0 interface */
        pwm = tsb_pwminitialize(0);
        if (!pwm) {
            adbg("Failed to get the TSB PWM0 lower half\n");
            return -ENODEV;
        }

        /* Register the PWM0 driver at "/dev/pwm0" */

        ret = pwm_register("/dev/pwm0", pwm);
        if (ret < 0) {
            adbg("pwm_register for /dev/pwm0 failed: %d\n", ret);
            return ret;
        }

        /* Now PWM0 is initialized */
        pwm0_initialized = 1;
    }

    /* Have we already initialized PWM1? */
    if (!pwm1_initialized) {
        /* Call tsb_pwminitialize() to get an instance of the PWM1 interface */
        pwm = tsb_pwminitialize(1);
        if (!pwm) {
            adbg("Failed to get the TSB PWM1 lower half\n");
            return -ENODEV;
        }

        /* Register the PWM1 driver at "/dev/pwm1" */
        ret = pwm_register("/dev/pwm1", pwm);
        if (ret < 0) {
            adbg("pwm_register for /dev/pwm1 failed: %d\n", ret);
            return ret;
        }

        /* Now PWM0 is initialized */
        pwm1_initialized = 1;
    }

    return 0;
}
示例#2
0
static void pwm_enable(void)
{
    struct pwm_lowerhalf_s *pwm;
    struct pwm_info_s pwm_info;
    int ret;
    int fd;

    pwm_info.frequency = 300000;
    pwm_info.duty = 32767;

    pwm = tsb_pwminitialize(0);
    if (!pwm) {
        lowsyslog("pwminitialize failed\n");
        return;
    }

    if (pwm_register("/dev/pwm0", pwm)) {
        lowsyslog("Can't register /dev/pwm0\n");
        return;
    }

    fd = open("/dev/pwm0", O_RDONLY);
    ret = ioctl(fd, PWMIOC_SETCHARACTERISTICS, (unsigned long)&pwm_info);
    if (ret < 0) {
        lowsyslog("pwm_main: ioctl(PWMIOC_SETCHARACTERISTICS) failed: %d\n",
                  errno);
    }

    ret = ioctl(fd, PWMIOC_START, 0);
    if (ret < 0) {
        lowsyslog("pwm_main: ioctl(PWMIOC_START) failed: %d\n", errno);
    }
}
示例#3
0
int pwm_devinit(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call kl_pwminitialize() to get an instance of the PWM interface */

      pwm = kl_pwminitialize(0);
      if (!pwm)
        {
          adbg("Failed to get the KL26 PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          adbg("pwm_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
示例#4
0
int board_pwm_setup(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call sam_pwminitialize() to get an instance of the PWM interface */

      pwm = sam_pwminitialize(CONFIG_SAMA5D3XPLAINED_CHANNEL);
      if (!pwm)
        {
          dbg("Failed to get the SAMA5 PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          adbg("pwm_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
示例#5
0
int board_pwm_setup(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call stm32_pwminitialize() to get an instance of the PWM interface */

      pwm = stm32_pwminitialize(NUCLEO_F303RE_PWMTIMER);
      if (pwm == NULL)
        {
          pwmerr("ERROR: Failed to get the STM32 PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          pwmerr("ERROR: pwm_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
示例#6
0
int board_pwm_setup(void)
{
#ifdef CONFIG_S5J_PWM
	struct pwm_lowerhalf_s *pwm;
	char path[10];
	int ret;
	int i;

	for (i = 0; i < 6; i++) {
		pwm = s5j_pwminitialize(i);
		if (!pwm) {
			lldbg("Failed to get the S5J PWM lower half\n");
			return -ENODEV;
		}

		/* Register the PWM driver at "/dev/pwmx" */
		snprintf(path, sizeof(path), "/dev/pwm%d", i);
		ret = pwm_register(path, pwm);
		if (ret < 0) {
			lldbg("pwm_register failed: %d\n", ret);
			return ret;
		}
	}
#endif

	return OK;
}
示例#7
0
bool iotjs_pwm_open(iotjs_pwm_t* pwm) {
  int timer = SYSIO_GET_TIMER(pwm->pin);
  char path[PWM_DEVICE_PATH_BUFFER_SIZE] = { 0 };

  if (snprintf(path, PWM_DEVICE_PATH_BUFFER_SIZE, PWM_DEVICE_PATH_FORMAT,
               timer) < 0) {
    return false;
  }

  struct pwm_lowerhalf_s* pwm_lowerhalf =
      iotjs_pwm_config_nuttx(timer, pwm->pin);

  DDDLOG("%s - path: %s, timer: %d\n", __func__, path, timer);

  if (pwm_register(path, pwm_lowerhalf) != 0) {
    return false;
  }

  // File open
  iotjs_pwm_platform_data_t* platform_data = pwm->platform_data;
  platform_data->device_fd = open(path, O_RDONLY);
  if (platform_data->device_fd < 0) {
    DLOG("%s - file open failed", __func__);
    return false;
  }

  if (!pwm_set_options(pwm)) {
    return false;
  }

  return true;
}
示例#8
0
文件: gpio-pwm.c 项目: 23171580/cpe
static int __devinit
gpio_pwm_probe(struct platform_device *pdev)
{
    struct gpio_pwm *gp;
    struct gpio_pwm_platform_data *gpd = pdev->dev.platform_data;
    int ret = 0;

    /* TODO: create configfs entries, so users can assign GPIOs to
     * PWMs at runtime instead of creating a platform_device
     * specification and rebuilding their kernel */

    if (!gpd || gpio_request(gpd->gpio, dev_name(&pdev->dev)))
        return -EINVAL;

    gp = kzalloc(sizeof(*gp), GFP_KERNEL);
    if (!gp) {
        ret = -ENOMEM;
        goto err_alloc;
    }

    platform_set_drvdata(pdev, gp);

    gp->pwm.dev = &pdev->dev;
    gp->pwm.bus_id = dev_name(&pdev->dev);
    gp->pwm.nchan = 1;
    gp->gpio = gpd->gpio;

    INIT_WORK(&gp->work, gpio_pwm_work);

    hrtimer_init(&gp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    gp->timer.function = gpio_pwm_timeout;

    gp->pwm.owner = THIS_MODULE;
    gp->pwm.config_nosleep = gpio_pwm_config_nosleep;
    gp->pwm.config = gpio_pwm_config;
    gp->pwm.request = gpio_pwm_request;
    gp->pwm.set_callback = gpio_pwm_set_callback;

    ret = pwm_register(&gp->pwm);
    if (ret)
        goto err_pwm_register;

    return 0;

err_pwm_register:
    platform_set_drvdata(pdev, 0);
    kfree(gp);
err_alloc:
    return ret;
}
示例#9
0
static int ecap_probe(struct platform_device *pdev)
{
	struct ecap_pwm *ep = NULL;
	struct resource *r;
	int ret = 0;
	int val;
	char con_id[PWM_CON_ID_STRING_LENGTH] = "epwmss";
	struct pwmss_platform_data *pdata = (&pdev->dev)->platform_data;

	ep = kzalloc(sizeof(*ep), GFP_KERNEL);

	if (!ep) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	ep->version = pdata->version;

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

	pm_runtime_irq_safe(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	ep->dev = &pdev->dev;
	if (IS_ERR(ep->clk)) {
		ret = PTR_ERR(ep->clk);
		goto err_clk_get;
	}

	if (ep->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_get_resource;
		}

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

		if (!ep->config_mem_base) {

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

		pm_runtime_get_sync(ep->dev);
		val = readw(ep->config_mem_base + PWMSS_CLKCONFIG);
		val |= BIT(ECAP_CLK_EN);
		writew(val, ep->config_mem_base + PWMSS_CLKCONFIG);
		pm_runtime_put_sync(ep->dev);
	}

	spin_lock_init(&ep->lock);
	ep->ops.config = ecap_pwm_config;
	ep->ops.request = ecap_pwm_request;
	ep->ops.freq_transition_notifier_cb = ecap_frequency_transition_cb;

	if (ep->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_request_mem;
	}

	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_mem;
	}

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

	ep->pwm.ops = &ep->ops;
	pwm_set_drvdata(&ep->pwm, ep);
	ret =  pwm_register(&ep->pwm, &pdev->dev, -1);
	platform_set_drvdata(pdev, ep);
	/* Inverse the polarity of PWM wave */
	if (pdata->chan_attrib[0].inverse_pol) {
		ep->pwm.active_high = 1;
		ecap_pwm_set_polarity(&ep->pwm, 1);
	}
	return 0;

err_ioremap:
	release_mem_region(r->start, resource_size(r));
err_request_mem:
	if (ep->version == PWM_VERSION_1) {
		iounmap(ep->config_mem_base);
		ep->config_mem_base = NULL;
	}
err_get_resource:
	clk_put(ep->clk);
	pm_runtime_disable(&pdev->dev);
err_clk_get:
	kfree(ep);
	return ret;
}
示例#10
0
int mbed_pwm_setup(void)
{
  static bool initialized = false;
  struct pwm_lowerhalf_s *pwm;
  struct pwm_lowerhalf_s *mcpwm;
  struct pwm_lowerhalf_s *timer;
  int ret;

  /* Have we already initialized? */

  if (!initialized)
    {
      /* Call lpc17_pwminitialize() to get an instance of the PWM interface */

      pwm = lpc17_pwminitialize(0);
      if (!pwm)
        {
          aerr("ERROR: Failed to get the LPC17XX PWM lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/pwm0" */

      ret = pwm_register("/dev/pwm0", pwm);
      if (ret < 0)
        {
          aerr("ERROR: pwm_register failed: %d\n", ret);
          return ret;
        }

      mcpwm = lpc17_mcpwminitialize(0);
      if (!mcpwm)
        {
          aerr("ERROR: Failed to get the LPC17XX MOTOR PWM lower half\n");
          return -ENODEV;
        }

      /* Register the MOTOR CONTROL PWM driver at "/dev/mcpwm0" */

      ret = pwm_register("/dev/mcpwm0", mcpwm);
      if (ret < 0)
        {
          aerr("ERROR: mcpwm_register failed: %d\n", ret);
          return ret;
        }

      timer = lpc17_timerinitialize(0);
      if (!timer)
        {
          aerr("ERROR: Failed to get the LPC17XX TIMER lower half\n");
          return -ENODEV;
        }

      /* Register the PWM driver at "/dev/timer0" */

      ret = pwm_register("/dev/timer0", timer);
      if (ret < 0)
        {
          aerr("ERROR: timer_register failed: %d\n", ret);
          return ret;
        }

      /* Now we are initialized */

      initialized = true;
    }

  return OK;
}
static int kona_pwmc_config(struct pwm_device *p, struct pwm_config *c)
{
	struct kona_pwmc *ap = pwm_get_drvdata(p);
	int chan = kona_get_chan(ap, p);
	int ret = 0;

	if (test_bit(PWM_CONFIG_POLARITY, &c->config_mask))
		kona_pwmc_config_polarity(ap, chan, c);

	if (test_bit(PWM_CONFIG_DUTY_TICKS, &c->config_mask))
		kona_pwmc_config_duty_ticks(ap, chan, c);

	if (test_bit(PWM_CONFIG_PERIOD_TICKS, &c->config_mask)) {
		ret = kona_pwmc_config_period_ticks(ap, chan, c);
		if (ret)
			goto out;

		if (!test_bit(PWM_CONFIG_DUTY_TICKS, &c->config_mask)) {
			struct pwm_config d = {
				.config_mask = PWM_CONFIG_DUTY_TICKS,
				.duty_ticks = p->duty_ticks,
			};
			kona_pwmc_config_duty_ticks(ap, chan, &d);
		}
	}

	if (!ap->pwm_started && test_bit(PWM_CONFIG_START, &c->config_mask)) {
		/* Restore duty ticks cater for STOP case. */
		struct pwm_config d = {
			.config_mask = PWM_CONFIG_DUTY_TICKS,
			.duty_ticks = p->duty_ticks,
		};

		ap->pwm_started = 1;
		usleep_range(3000, 7000);
		clk_enable(ap->clk);
		kona_pwmc_clear_set_bit(ap, pwm_chan_ctrl_info[chan].offset,
					pwm_chan_ctrl_info[chan].
					smooth_type_shift, 1);
		kona_pwmc_config_duty_ticks(ap, chan, &d);
		kona_pwmc_start(ap, chan);
	}

	if (ap->pwm_started && test_bit(PWM_CONFIG_STOP, &c->config_mask)) {
		struct pwm_config d = {
			.config_mask = PWM_CONFIG_DUTY_TICKS,
			.duty_ticks = 0,
		};

		ap->pwm_started = 0;
		kona_pwmc_config_duty_ticks(ap, chan, &d);
		kona_pwmc_clear_set_bit(ap, pwm_chan_ctrl_info[chan].offset,
					pwm_chan_ctrl_info[chan].
					smooth_type_shift, 0);
		/* turn-off the PWM clock i.e. enabled during pwm_start */
		ndelay(410);
		clk_disable(ap->clk);
	}

out:
	return ret;
}

static int kona_pwmc_request(struct pwm_device *p)
{
	struct kona_pwmc *ap = pwm_get_drvdata(p);
	int chan = kona_get_chan(ap, p);
	clk_enable(ap->clk);
	p->tick_hz = clk_get_rate(ap->clk);
	kona_pwmc_stop(ap, chan);
	clk_disable(ap->clk);
	return 0;
}

static void kona_pwmc_release(struct pwm_device *p)
{

}


static const struct pwm_device_ops kona_pwm_ops = {
	.request = kona_pwmc_request,
	.release = kona_pwmc_release,
	.config = kona_pwmc_config,
	.owner = THIS_MODULE,
};

static int __devinit kona_pwmc_probe(struct platform_device *pdev)
{
	struct kona_pwmc *ap;
	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	int chan;
	int ret = 0;

	ap = kzalloc(sizeof(*ap), GFP_KERNEL);
	if (!ap) {
		ret = -ENOMEM;
		goto err_kona_pwmc_alloc;
	}

	platform_set_drvdata(pdev, ap);
	ap->clk = clk_get(&pdev->dev, "pwm_clk");
	if (IS_ERR(ap->clk)) {
		ret = -ENODEV;
		goto err_clk_get;
	}

	ap->iobase = ioremap_nocache(r->start, resource_size(r));
	if (!ap->iobase) {
		ret = -ENODEV;
		goto err_ioremap;
	}

	for (chan = 0; chan < KONA_PWM_CHANNEL_CNT; chan++) {
		ap->p[chan] = pwm_register(&kona_pwm_ops, &pdev->dev, "%s:%d",
					   "kona_pwmc", chan);
		if (IS_ERR_OR_NULL(ap->p[chan]))
			goto err_pwm_register;
		pwm_set_drvdata(ap->p[chan], ap);
		kona_pwmc_clear_set_bit(ap, pwm_chan_ctrl_info[chan].offset,
					pwm_chan_ctrl_info[chan].
					smooth_type_shift, 1);
	}

	printk(KERN_INFO "PWM: driver initialized properly");

	return 0;

err_pwm_register:
	while (--chan > 0)
		pwm_unregister(ap->p[chan]);

	iounmap(ap->iobase);
err_ioremap:
	clk_put(ap->clk);
err_clk_get:
	platform_set_drvdata(pdev, NULL);
	kfree(ap);
err_kona_pwmc_alloc:
	printk(KERN_ERR "%s: error, returning %d\n", __func__, ret);
	return ret;
}

static int __devexit kona_pwmc_remove(struct platform_device *pdev)
{
	struct kona_pwmc *ap = platform_get_drvdata(pdev);
	int chan;

	for (chan = 0; chan < KONA_PWM_CHANNEL_CNT; chan++)
		pwm_unregister(ap->p[chan]);

	clk_put(ap->clk);
	iounmap(ap->iobase);

	kfree(ap);

	return 0;
}

#ifdef CONFIG_PM
static int kona_pwmc_suspend(struct platform_device *pdev, pm_message_t state)
{
	/* TODO: add more resume support in the future */
	return 0;
}

static int kona_pwmc_resume(struct platform_device *pdev)
{
	/* TODO: add more resume support in the future */
	return 0;
}
#else
#define kona_pwmc_suspend    NULL
#define kona_pwmc_resume     NULL
#endif

static const struct of_device_id kona_pwmc_dt_ids[] = {
	{ .compatible = "bcm,pwmc", },
	{}
};
示例#12
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;
}
示例#13
0
static int ehrpwm_probe(struct platform_device *pdev)
{
	struct ehrpwm_pwm *ehrpwm = NULL;
	struct resource *r;
	int ret = 0;
	int chan = 0;
	struct ehrpwm_platform_data *pdata = (&pdev->dev)->platform_data;
	int ch_mask;

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

	ehrpwm->clk = clk_get(&pdev->dev, "ehrpwm");
	if (IS_ERR(ehrpwm->clk)) {
		ret = PTR_ERR(ehrpwm->clk);
		goto err_free_device;
	}

	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;
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "no memory resource defined\n");
		ret = -ENODEV;
		goto err_free_clk;
	}

	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_free_clk;
	}

	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_mem;
	}

	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);
		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_mem:
	release_mem_region(r->start, resource_size(r));
err_free_clk:
	clk_put(ehrpwm->clk);
err_free_device:
	kfree(ehrpwm);
	return ret;
}
示例#14
0
static int __devinit ecap_probe(struct platform_device *pdev)
{
	struct ecap_pwm *ep = NULL;
	struct resource *r;
	int ret = 0;

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

	ep->clk = clk_get(&pdev->dev, "ecap");
	if (IS_ERR(ep->clk)) {
		ret = PTR_ERR(ep->clk);
		goto err_free;
	}

	spin_lock_init(&ep->lock);
	ep->ops.config = ecap_pwm_config;
	ep->ops.request = ecap_pwm_request;
	ep->ops.freq_transition_notifier_cb = ecap_frequency_transition_cb;
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "no memory resource defined\n");
		ret = -ENODEV;
		goto err_free_clk;
	}

	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_free_clk;
	}

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

	__raw_writew(ECTRL2_APWM | ECTRL2_SYNCO_SEL,
		     ep->mmio_base + CAPTURE_CTRL2_REG);
	__raw_writel(0, ep->mmio_base + TIMER_CTR_REG);
	__raw_writel(0, ep->mmio_base + PHASE_CTR_REG);
	__raw_writel(~0, ep->mmio_base + CAPTURE_1_REG); /* period */
	__raw_writel(0, ep->mmio_base + CAPTURE_2_REG); /* duty */

	ep->pwm.ops = &ep->ops;
	pwm_set_drvdata(&ep->pwm, ep);
	ret =  pwm_register(&ep->pwm, &pdev->dev, -1);
	platform_set_drvdata(pdev, ep);
	return 0;

err_free_mem:
	release_mem_region(r->start, resource_size(r));
err_free_clk:
	clk_put(ep->clk);
err_free:
	kfree(ep);
err_ecap_pwm_alloc:
	return ret;
}