aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/Kconfig13
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/ep93xx_pwm.c286
-rw-r--r--drivers/pwm/Kconfig9
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/pwm-ep93xx.c230
6 files changed, 240 insertions, 300 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8dacd4c9ee87..c43c66ad5721 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -381,19 +381,6 @@ config HMC6352
381 This driver provides support for the Honeywell HMC6352 compass, 381 This driver provides support for the Honeywell HMC6352 compass,
382 providing configuration and heading data via sysfs. 382 providing configuration and heading data via sysfs.
383 383
384config EP93XX_PWM
385 tristate "EP93xx PWM support"
386 depends on ARCH_EP93XX
387 help
388 This option enables device driver support for the PWM channels
389 on the Cirrus EP93xx processors. The EP9307 chip only has one
390 PWM channel all the others have two, the second channel is an
391 alternate function of the EGPIO14 pin. A sysfs interface is
392 provided to control the PWM channels.
393
394 To compile this driver as a module, choose M here: the module will
395 be called ep93xx_pwm.
396
397config DS1682 384config DS1682
398 tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" 385 tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
399 depends on I2C 386 depends on I2C
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c235d5b68311..ecccd0039353 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_APDS9802ALS) += apds9802als.o
33obj-$(CONFIG_ISL29003) += isl29003.o 33obj-$(CONFIG_ISL29003) += isl29003.o
34obj-$(CONFIG_ISL29020) += isl29020.o 34obj-$(CONFIG_ISL29020) += isl29020.o
35obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o 35obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
36obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
37obj-$(CONFIG_DS1682) += ds1682.o 36obj-$(CONFIG_DS1682) += ds1682.o
38obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o 37obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
39obj-$(CONFIG_C2PORT) += c2port/ 38obj-$(CONFIG_C2PORT) += c2port/
diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c
deleted file mode 100644
index cdb67a9c1959..000000000000
--- a/drivers/misc/ep93xx_pwm.c
+++ /dev/null
@@ -1,286 +0,0 @@
1/*
2 * Simple PWM driver for EP93XX
3 *
4 * (c) Copyright 2009 Matthieu Crapet <mcrapet@gmail.com>
5 * (c) Copyright 2009 H Hartley Sweeten <hsweeten@visionengravers.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * EP9307 has only one channel:
13 * - PWMOUT
14 *
15 * EP9301/02/12/15 have two channels:
16 * - PWMOUT
17 * - PWMOUT1 (alternate function for EGPIO14)
18 */
19
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/io.h>
26
27#include <mach/platform.h>
28
29#define EP93XX_PWMx_TERM_COUNT 0x00
30#define EP93XX_PWMx_DUTY_CYCLE 0x04
31#define EP93XX_PWMx_ENABLE 0x08
32#define EP93XX_PWMx_INVERT 0x0C
33
34#define EP93XX_PWM_MAX_COUNT 0xFFFF
35
36struct ep93xx_pwm {
37 void __iomem *mmio_base;
38 struct clk *clk;
39 u32 duty_percent;
40};
41
42/*
43 * /sys/devices/platform/ep93xx-pwm.N
44 * /min_freq read-only minimum pwm output frequency
45 * /max_req read-only maximum pwm output frequency
46 * /freq read-write pwm output frequency (0 = disable output)
47 * /duty_percent read-write pwm duty cycle percent (1..99)
48 * /invert read-write invert pwm output
49 */
50
51static ssize_t ep93xx_pwm_get_min_freq(struct device *dev,
52 struct device_attribute *attr, char *buf)
53{
54 struct platform_device *pdev = to_platform_device(dev);
55 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
56 unsigned long rate = clk_get_rate(pwm->clk);
57
58 return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1));
59}
60
61static ssize_t ep93xx_pwm_get_max_freq(struct device *dev,
62 struct device_attribute *attr, char *buf)
63{
64 struct platform_device *pdev = to_platform_device(dev);
65 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
66 unsigned long rate = clk_get_rate(pwm->clk);
67
68 return sprintf(buf, "%ld\n", rate / 2);
69}
70
71static ssize_t ep93xx_pwm_get_freq(struct device *dev,
72 struct device_attribute *attr, char *buf)
73{
74 struct platform_device *pdev = to_platform_device(dev);
75 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
76
77 if (readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1) {
78 unsigned long rate = clk_get_rate(pwm->clk);
79 u16 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
80
81 return sprintf(buf, "%ld\n", rate / (term + 1));
82 } else {
83 return sprintf(buf, "disabled\n");
84 }
85}
86
87static ssize_t ep93xx_pwm_set_freq(struct device *dev,
88 struct device_attribute *attr, const char *buf, size_t count)
89{
90 struct platform_device *pdev = to_platform_device(dev);
91 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
92 long val;
93 int err;
94
95 err = kstrtol(buf, 10, &val);
96 if (err)
97 return -EINVAL;
98
99 if (val == 0) {
100 writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE);
101 } else if (val <= (clk_get_rate(pwm->clk) / 2)) {
102 u32 term, duty;
103
104 val = (clk_get_rate(pwm->clk) / val) - 1;
105 if (val > EP93XX_PWM_MAX_COUNT)
106 val = EP93XX_PWM_MAX_COUNT;
107 if (val < 1)
108 val = 1;
109
110 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
111 duty = ((val + 1) * pwm->duty_percent / 100) - 1;
112
113 /* If pwm is running, order is important */
114 if (val > term) {
115 writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
116 writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
117 } else {
118 writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
119 writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
120 }
121
122 if (!readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1)
123 writel(0x1, pwm->mmio_base + EP93XX_PWMx_ENABLE);
124 } else {
125 return -EINVAL;
126 }
127
128 return count;
129}
130
131static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev,
132 struct device_attribute *attr, char *buf)
133{
134 struct platform_device *pdev = to_platform_device(dev);
135 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
136
137 return sprintf(buf, "%d\n", pwm->duty_percent);
138}
139
140static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev,
141 struct device_attribute *attr, const char *buf, size_t count)
142{
143 struct platform_device *pdev = to_platform_device(dev);
144 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
145 long val;
146 int err;
147
148 err = kstrtol(buf, 10, &val);
149 if (err)
150 return -EINVAL;
151
152 if (val > 0 && val < 100) {
153 u32 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
154 u32 duty = ((term + 1) * val / 100) - 1;
155
156 writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
157 pwm->duty_percent = val;
158 return count;
159 }
160
161 return -EINVAL;
162}
163
164static ssize_t ep93xx_pwm_get_invert(struct device *dev,
165 struct device_attribute *attr, char *buf)
166{
167 struct platform_device *pdev = to_platform_device(dev);
168 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
169 int inverted = readl(pwm->mmio_base + EP93XX_PWMx_INVERT) & 0x1;
170
171 return sprintf(buf, "%d\n", inverted);
172}
173
174static ssize_t ep93xx_pwm_set_invert(struct device *dev,
175 struct device_attribute *attr, const char *buf, size_t count)
176{
177 struct platform_device *pdev = to_platform_device(dev);
178 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
179 long val;
180 int err;
181
182 err = kstrtol(buf, 10, &val);
183 if (err)
184 return -EINVAL;
185
186 if (val == 0)
187 writel(0x0, pwm->mmio_base + EP93XX_PWMx_INVERT);
188 else if (val == 1)
189 writel(0x1, pwm->mmio_base + EP93XX_PWMx_INVERT);
190 else
191 return -EINVAL;
192
193 return count;
194}
195
196static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL);
197static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL);
198static DEVICE_ATTR(freq, S_IWUSR | S_IRUGO,
199 ep93xx_pwm_get_freq, ep93xx_pwm_set_freq);
200static DEVICE_ATTR(duty_percent, S_IWUSR | S_IRUGO,
201 ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent);
202static DEVICE_ATTR(invert, S_IWUSR | S_IRUGO,
203 ep93xx_pwm_get_invert, ep93xx_pwm_set_invert);
204
205static struct attribute *ep93xx_pwm_attrs[] = {
206 &dev_attr_min_freq.attr,
207 &dev_attr_max_freq.attr,
208 &dev_attr_freq.attr,
209 &dev_attr_duty_percent.attr,
210 &dev_attr_invert.attr,
211 NULL
212};
213
214static const struct attribute_group ep93xx_pwm_sysfs_files = {
215 .attrs = ep93xx_pwm_attrs,
216};
217
218static int ep93xx_pwm_probe(struct platform_device *pdev)
219{
220 struct ep93xx_pwm *pwm;
221 struct resource *res;
222 int ret;
223
224 pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
225 if (!pwm)
226 return -ENOMEM;
227
228 pwm->clk = devm_clk_get(&pdev->dev, "pwm_clk");
229 if (IS_ERR(pwm->clk))
230 return PTR_ERR(pwm->clk);
231
232 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
233 pwm->mmio_base = devm_ioremap_resource(&pdev->dev, res);
234 if (IS_ERR(pwm->mmio_base))
235 return PTR_ERR(pwm->mmio_base);
236
237 ret = ep93xx_pwm_acquire_gpio(pdev);
238 if (ret)
239 return ret;
240
241 ret = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
242 if (ret) {
243 ep93xx_pwm_release_gpio(pdev);
244 return ret;
245 }
246
247 pwm->duty_percent = 50;
248
249 /* disable pwm at startup. Avoids zero value. */
250 writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE);
251 writel(EP93XX_PWM_MAX_COUNT, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
252 writel(EP93XX_PWM_MAX_COUNT/2, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
253
254 clk_enable(pwm->clk);
255
256 platform_set_drvdata(pdev, pwm);
257 return 0;
258}
259
260static int ep93xx_pwm_remove(struct platform_device *pdev)
261{
262 struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
263
264 writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE);
265 clk_disable(pwm->clk);
266 sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
267 ep93xx_pwm_release_gpio(pdev);
268
269 return 0;
270}
271
272static struct platform_driver ep93xx_pwm_driver = {
273 .driver = {
274 .name = "ep93xx-pwm",
275 .owner = THIS_MODULE,
276 },
277 .probe = ep93xx_pwm_probe,
278 .remove = ep93xx_pwm_remove,
279};
280module_platform_driver(ep93xx_pwm_driver);
281
282MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, "
283 "H Hartley Sweeten <hsweeten@visionengravers.com>");
284MODULE_DESCRIPTION("EP93xx PWM driver");
285MODULE_LICENSE("GPL");
286MODULE_ALIAS("platform:ep93xx-pwm");
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 75840b5cea6d..eece329d7872 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -62,6 +62,15 @@ config PWM_BFIN
62 To compile this driver as a module, choose M here: the module 62 To compile this driver as a module, choose M here: the module
63 will be called pwm-bfin. 63 will be called pwm-bfin.
64 64
65config PWM_EP93XX
66 tristate "Cirrus Logic EP93xx PWM support"
67 depends on ARCH_EP93XX
68 help
69 Generic PWM framework driver for Cirrus Logic EP93xx.
70
71 To compile this driver as a module, choose M here: the module
72 will be called pwm-ep93xx.
73
65config PWM_IMX 74config PWM_IMX
66 tristate "i.MX PWM support" 75 tristate "i.MX PWM support"
67 depends on ARCH_MXC 76 depends on ARCH_MXC
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c185c5b2..8b754e4dba4a 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_PWM_SYSFS) += sysfs.o
3obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o 3obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
4obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o 4obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
5obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o 5obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
6obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
6obj-$(CONFIG_PWM_IMX) += pwm-imx.o 7obj-$(CONFIG_PWM_IMX) += pwm-imx.o
7obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o 8obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
8obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o 9obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c
new file mode 100644
index 000000000000..33aa4461e1ce
--- /dev/null
+++ b/drivers/pwm/pwm-ep93xx.c
@@ -0,0 +1,230 @@
1/*
2 * PWM framework driver for Cirrus Logic EP93xx
3 *
4 * Copyright (c) 2009 Matthieu Crapet <mcrapet@gmail.com>
5 * Copyright (c) 2009, 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
6 *
7 * EP9301/02 have only one channel:
8 * platform device ep93xx-pwm.1 - PWMOUT1 (EGPIO14)
9 *
10 * EP9307 has only one channel:
11 * platform device ep93xx-pwm.0 - PWMOUT
12 *
13 * EP9312/15 have two channels:
14 * platform device ep93xx-pwm.0 - PWMOUT
15 * platform device ep93xx-pwm.1 - PWMOUT1 (EGPIO14)
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version
20 * 2 of the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 */
27
28#include <linux/module.h>
29#include <linux/platform_device.h>
30#include <linux/slab.h>
31#include <linux/clk.h>
32#include <linux/err.h>
33#include <linux/io.h>
34#include <linux/pwm.h>
35
36#include <asm/div64.h>
37
38#include <mach/platform.h> /* for ep93xx_pwm_{acquire,release}_gpio() */
39
40#define EP93XX_PWMx_TERM_COUNT 0x00
41#define EP93XX_PWMx_DUTY_CYCLE 0x04
42#define EP93XX_PWMx_ENABLE 0x08
43#define EP93XX_PWMx_INVERT 0x0c
44
45struct ep93xx_pwm {
46 void __iomem *base;
47 struct clk *clk;
48 struct pwm_chip chip;
49};
50
51static inline struct ep93xx_pwm *to_ep93xx_pwm(struct pwm_chip *chip)
52{
53 return container_of(chip, struct ep93xx_pwm, chip);
54}
55
56static int ep93xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
57{
58 struct platform_device *pdev = to_platform_device(chip->dev);
59
60 return ep93xx_pwm_acquire_gpio(pdev);
61}
62
63static void ep93xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
64{
65 struct platform_device *pdev = to_platform_device(chip->dev);
66
67 ep93xx_pwm_release_gpio(pdev);
68}
69
70static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
71 int duty_ns, int period_ns)
72{
73 struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
74 void __iomem *base = ep93xx_pwm->base;
75 unsigned long long c;
76 unsigned long period_cycles;
77 unsigned long duty_cycles;
78 unsigned long term;
79 int ret = 0;
80
81 /*
82 * The clock needs to be enabled to access the PWM registers.
83 * Configuration can be changed at any time.
84 */
85 if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
86 ret = clk_enable(ep93xx_pwm->clk);
87 if (ret)
88 return ret;
89 }
90
91 c = clk_get_rate(ep93xx_pwm->clk);
92 c *= period_ns;
93 do_div(c, 1000000000);
94 period_cycles = c;
95
96 c = period_cycles;
97 c *= duty_ns;
98 do_div(c, period_ns);
99 duty_cycles = c;
100
101 if (period_cycles < 0x10000 && duty_cycles < 0x10000) {
102 term = readw(base + EP93XX_PWMx_TERM_COUNT);
103
104 /* Order is important if PWM is running */
105 if (period_cycles > term) {
106 writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
107 writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
108 } else {
109 writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
110 writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
111 }
112 } else {
113 ret = -EINVAL;
114 }
115
116 if (!test_bit(PWMF_ENABLED, &pwm->flags))
117 clk_disable(ep93xx_pwm->clk);
118
119 return ret;
120}
121
122static int ep93xx_pwm_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
123 enum pwm_polarity polarity)
124{
125 struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
126 int ret;
127
128 /*
129 * The clock needs to be enabled to access the PWM registers.
130 * Polarity can only be changed when the PWM is disabled.
131 */
132 ret = clk_enable(ep93xx_pwm->clk);
133 if (ret)
134 return ret;
135
136 if (polarity == PWM_POLARITY_INVERSED)
137 writew(0x1, ep93xx_pwm->base + EP93XX_PWMx_INVERT);
138 else
139 writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_INVERT);
140
141 clk_disable(ep93xx_pwm->clk);
142
143 return 0;
144}
145
146static int ep93xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
147{
148 struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
149 int ret;
150
151 ret = clk_enable(ep93xx_pwm->clk);
152 if (ret)
153 return ret;
154
155 writew(0x1, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
156
157 return 0;
158}
159
160static void ep93xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
161{
162 struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
163
164 writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
165 clk_disable(ep93xx_pwm->clk);
166}
167
168static const struct pwm_ops ep93xx_pwm_ops = {
169 .request = ep93xx_pwm_request,
170 .free = ep93xx_pwm_free,
171 .config = ep93xx_pwm_config,
172 .set_polarity = ep93xx_pwm_polarity,
173 .enable = ep93xx_pwm_enable,
174 .disable = ep93xx_pwm_disable,
175 .owner = THIS_MODULE,
176};
177
178static int ep93xx_pwm_probe(struct platform_device *pdev)
179{
180 struct ep93xx_pwm *ep93xx_pwm;
181 struct resource *res;
182 int ret;
183
184 ep93xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_pwm), GFP_KERNEL);
185 if (!ep93xx_pwm)
186 return -ENOMEM;
187
188 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
189 ep93xx_pwm->base = devm_ioremap_resource(&pdev->dev, res);
190 if (IS_ERR(ep93xx_pwm->base))
191 return PTR_ERR(ep93xx_pwm->base);
192
193 ep93xx_pwm->clk = devm_clk_get(&pdev->dev, "pwm_clk");
194 if (IS_ERR(ep93xx_pwm->clk))
195 return PTR_ERR(ep93xx_pwm->clk);
196
197 ep93xx_pwm->chip.dev = &pdev->dev;
198 ep93xx_pwm->chip.ops = &ep93xx_pwm_ops;
199 ep93xx_pwm->chip.base = -1;
200 ep93xx_pwm->chip.npwm = 1;
201
202 ret = pwmchip_add(&ep93xx_pwm->chip);
203 if (ret < 0)
204 return ret;
205
206 platform_set_drvdata(pdev, ep93xx_pwm);
207 return 0;
208}
209
210static int ep93xx_pwm_remove(struct platform_device *pdev)
211{
212 struct ep93xx_pwm *ep93xx_pwm = platform_get_drvdata(pdev);
213
214 return pwmchip_remove(&ep93xx_pwm->chip);
215}
216
217static struct platform_driver ep93xx_pwm_driver = {
218 .driver = {
219 .name = "ep93xx-pwm",
220 },
221 .probe = ep93xx_pwm_probe,
222 .remove = ep93xx_pwm_remove,
223};
224module_platform_driver(ep93xx_pwm_driver);
225
226MODULE_DESCRIPTION("Cirrus Logic EP93xx PWM driver");
227MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, "
228 "H Hartley Sweeten <hsweeten@visionengravers.com>");
229MODULE_ALIAS("platform:ep93xx-pwm");
230MODULE_LICENSE("GPL");