1 #include <linux/module.h>
2 #include <linux/platform_device.h>
3 #include <linux/mod_devicetable.h>
5 #include <asm-powerpc/mpc52xx.h>
6 #include <linux/interrupt.h>
9 struct mpc52xx_gpt *pwmf, *pwmb;
15 static ssize_t show_position(struct device *dev,
16 struct device_attribute *attr, char *buf)
18 struct platform_device *pdev = to_platform_device(dev);
19 struct motorek *m = platform_get_drvdata(pdev);
21 int len = snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&m->pos));
22 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
25 static ssize_t show_action(struct device *dev,
26 struct device_attribute *attr, char *buf)
28 struct platform_device *pdev = to_platform_device(dev);
29 struct motorek *m = platform_get_drvdata(pdev);
31 int len = snprintf(buf, PAGE_SIZE, "%d\n", m->action);
32 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
35 static void motorek_action(struct motorek *m, int action_permile);
36 static ssize_t store_action(struct device *dev, struct device_attribute *attr,
37 const char *buf, size_t count)
39 struct platform_device *pdev = to_platform_device(dev);
40 struct motorek *m = platform_get_drvdata(pdev);
43 sscanf(buf, "%d", &a);
45 return strnlen(buf, PAGE_SIZE);
48 DEVICE_ATTR(position,0444,show_position,NULL);
49 DEVICE_ATTR(action,0644,show_action,store_action);
51 #define MPC52xx_GPT_MODE_DISABLED 0
52 #define MPC52xx_GPT_MODE_INCAPT 1
53 #define MPC52xx_GPT_MODE_OUTCMP 2
54 #define MPC52xx_GPT_MODE_PWM 3
55 #define MPC52xx_GPT_MODE_GPIO 4
57 #define MPC52xx_GPT_PWM_OP (1<<8)
60 * (/proc/device-tree/cpus/PowerPC,5200@0/bus-frequency) */
61 #define PWM_PERIOD 6600 /* = 132 000 kHz / 20 kHz */
64 static void pwm_width(struct mpc52xx_gpt *gpt, u16 width)
66 out_be32(&gpt->pwm, (width<<16) | MPC52xx_GPT_PWM_OP);
69 static void __devinit pwm_init(struct mpc52xx_gpt *gpt)
71 out_be32(&gpt->count, (1<<16) | PWM_PERIOD);
73 out_be32(&gpt->mode, MPC52xx_GPT_MODE_PWM);
76 static void pwm_done(struct mpc52xx_gpt *gpt)
78 out_be32(&gpt->mode, 0);
79 out_be32(&gpt->count, 0);
83 static void motorek_action(struct motorek *m, int action_permile)
85 m->action = action_permile;
86 if (action_permile >= 0) {
87 pwm_width(m->pwmb, 0);
88 pwm_width(m->pwmf, +action_permile*PWM_PERIOD/1000);
90 pwm_width(m->pwmf, 0);
91 pwm_width(m->pwmb, -action_permile*PWM_PERIOD/1000);
95 static int __devinit motorek_init(struct motorek *m)
99 //motorek_action(m, +0);
103 static int motorek_done(struct motorek *m)
110 static irqreturn_t motorek_irq(int irq, void *dev_id)
112 struct motorek *m = dev_id;
117 /* mpc5200 device tree match tables */
118 static struct of_device_id mpc5200_gpt_ids[] __initdata = {
119 { .compatible = "fsl,mpc5200-gpt", },
120 { .compatible = "mpc5200-gpt", },
124 static int __devinit motorek_probe(struct platform_device *dev)
126 struct device_node *np;
130 m = kzalloc(sizeof(*m), GFP_KERNEL);
134 for_each_matching_node(np, mpc5200_gpt_ids) {
138 prop = of_get_property(np, "cell-index", NULL);
143 m->pwmf = of_iomap(np, 0);
146 m->pwmb = of_iomap(np, 0);
151 if (!m->pwmf || !m->pwmb) {
152 printk(KERN_ERR "%s() mmap failed\n", __func__);
156 /* /\* FIXME: This should be specified in device-tree *\/ */
157 /* m->irq = irq_create_of_mapping( */
159 /* err = request_irq(m->irq, motorek_irq, 0, "motorek", m); */
165 platform_set_drvdata(dev, m);
167 err = device_create_file(&dev->dev,&dev_attr_position);
170 err = device_create_file(&dev->dev,&dev_attr_action);
174 printk(KERN_NOTICE "Motorek initialized\n");
179 static int __devexit motorek_remove(struct platform_device *dev)
182 m = platform_get_drvdata(dev);
184 printk(KERN_NOTICE "Removing motorek\n");
192 static struct platform_driver motorek_driver = {
193 .probe = motorek_probe,
194 .remove = __devexit_p(motorek_remove),
197 .owner = THIS_MODULE,
202 static struct platform_device *motorek_pdev;
204 static int __init motorek_init_module(void)
207 motorek_pdev = platform_device_alloc("motorek", 0);
210 ret = platform_device_add(motorek_pdev);
212 platform_device_put(motorek_pdev);
216 ret = platform_driver_register(&motorek_driver);
219 module_init(motorek_init_module);
221 static void __exit motorek_exit_module(void)
223 platform_device_unregister(motorek_pdev);
224 platform_driver_unregister(&motorek_driver);
226 module_exit(motorek_exit_module);
229 MODULE_LICENSE("GPL v2");
230 MODULE_VERSION("0.1");
231 MODULE_AUTHOR("Michal Sojka <sojkam1@fel.cvut.cz>");