Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/pwm/pwm-bfin.c

  1 /*
  2  * Blackfin Pulse Width Modulation (PWM) core
  3  *
  4  * Copyright (c) 2011 Analog Devices Inc.
  5  *
  6  * Licensed under the GPL-2 or later.
  7  */
  8 
  9 #include <linux/module.h>
 10 #include <linux/platform_device.h>
 11 #include <linux/pwm.h>
 12 #include <linux/slab.h>
 13 
 14 #include <asm/gptimers.h>
 15 #include <asm/portmux.h>
 16 
 17 struct bfin_pwm_chip {
 18         struct pwm_chip chip;
 19 };
 20 
 21 struct bfin_pwm {
 22         unsigned short pin;
 23 };
 24 
 25 static const unsigned short pwm_to_gptimer_per[] = {
 26         P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR4, P_TMR5,
 27         P_TMR6, P_TMR7, P_TMR8, P_TMR9, P_TMR10, P_TMR11,
 28 };
 29 
 30 static int bfin_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 31 {
 32         struct bfin_pwm *priv;
 33         int ret;
 34 
 35         if (pwm->hwpwm >= ARRAY_SIZE(pwm_to_gptimer_per))
 36                 return -EINVAL;
 37 
 38         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 39         if (!priv)
 40                 return -ENOMEM;
 41 
 42         priv->pin = pwm_to_gptimer_per[pwm->hwpwm];
 43 
 44         ret = peripheral_request(priv->pin, NULL);
 45         if (ret) {
 46                 kfree(priv);
 47                 return ret;
 48         }
 49 
 50         pwm_set_chip_data(pwm, priv);
 51 
 52         return 0;
 53 }
 54 
 55 static void bfin_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 56 {
 57         struct bfin_pwm *priv = pwm_get_chip_data(pwm);
 58 
 59         if (priv) {
 60                 peripheral_free(priv->pin);
 61                 kfree(priv);
 62         }
 63 }
 64 
 65 static int bfin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 66                 int duty_ns, int period_ns)
 67 {
 68         struct bfin_pwm *priv = pwm_get_chip_data(pwm);
 69         unsigned long period, duty;
 70         unsigned long long val;
 71 
 72         val = (unsigned long long)get_sclk() * period_ns;
 73         do_div(val, NSEC_PER_SEC);
 74         period = val;
 75 
 76         val = (unsigned long long)period * duty_ns;
 77         do_div(val, period_ns);
 78         duty = period - val;
 79 
 80         if (duty >= period)
 81                 duty = period - 1;
 82 
 83         set_gptimer_config(priv->pin, TIMER_MODE_PWM | TIMER_PERIOD_CNT);
 84         set_gptimer_pwidth(priv->pin, duty);
 85         set_gptimer_period(priv->pin, period);
 86 
 87         return 0;
 88 }
 89 
 90 static int bfin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 91 {
 92         struct bfin_pwm *priv = pwm_get_chip_data(pwm);
 93 
 94         enable_gptimer(priv->pin);
 95 
 96         return 0;
 97 }
 98 
 99 static void bfin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
100 {
101         struct bfin_pwm *priv = pwm_get_chip_data(pwm);
102 
103         disable_gptimer(priv->pin);
104 }
105 
106 static struct pwm_ops bfin_pwm_ops = {
107         .request = bfin_pwm_request,
108         .free = bfin_pwm_free,
109         .config = bfin_pwm_config,
110         .enable = bfin_pwm_enable,
111         .disable = bfin_pwm_disable,
112         .owner = THIS_MODULE,
113 };
114 
115 static int bfin_pwm_probe(struct platform_device *pdev)
116 {
117         struct bfin_pwm_chip *pwm;
118         int ret;
119 
120         pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
121         if (!pwm) {
122                 dev_err(&pdev->dev, "failed to allocate memory\n");
123                 return -ENOMEM;
124         }
125 
126         platform_set_drvdata(pdev, pwm);
127 
128         pwm->chip.dev = &pdev->dev;
129         pwm->chip.ops = &bfin_pwm_ops;
130         pwm->chip.base = -1;
131         pwm->chip.npwm = 12;
132 
133         ret = pwmchip_add(&pwm->chip);
134         if (ret < 0) {
135                 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
136                 return ret;
137         }
138 
139         return 0;
140 }
141 
142 static int bfin_pwm_remove(struct platform_device *pdev)
143 {
144         struct bfin_pwm_chip *pwm = platform_get_drvdata(pdev);
145 
146         return pwmchip_remove(&pwm->chip);
147 }
148 
149 static struct platform_driver bfin_pwm_driver = {
150         .driver = {
151                 .name = "bfin-pwm",
152                 .owner = THIS_MODULE,
153         },
154         .probe = bfin_pwm_probe,
155         .remove = bfin_pwm_remove,
156 };
157 
158 module_platform_driver(bfin_pwm_driver);
159 
160 MODULE_LICENSE("GPL");
161 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us