]> rtime.felk.cvut.cz Git - shark/motorek-5200.git/blobdiff - motorek.c
Setup PWMs according to OF
[shark/motorek-5200.git] / motorek.c
index 83ee1d8cfbdaf7dcbc9a14aeb08e9b992199367a..4c69cb672b17f4d18410c725a9bc350e18f0eb30 100644 (file)
--- a/motorek.c
+++ b/motorek.c
@@ -2,6 +2,7 @@
 #include <linux/platform_device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <asm-powerpc/mpc52xx.h>
 #include <linux/interrupt.h>
 
@@ -9,6 +10,7 @@ struct motorek {
        struct mpc52xx_gpt *pwmf, *pwmb;
        atomic_t pos;
        int irq;
+       int action;
 };
 
 static ssize_t show_position(struct device *dev,
@@ -21,7 +23,31 @@ static ssize_t show_position(struct device *dev,
        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
 }
 
+static ssize_t show_action(struct device *dev,
+                          struct device_attribute *attr, char *buf)
+{
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct motorek          *m = platform_get_drvdata(pdev);
+
+       int len = snprintf(buf, PAGE_SIZE, "%d\n", m->action);
+       return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
+}
+
+static void motorek_action(struct motorek *m, int action_permile);
+static ssize_t store_action(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+{
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct motorek          *m = platform_get_drvdata(pdev);
+
+       int a;
+       sscanf(buf, "%d", &a);
+       motorek_action(m, a);
+       return strnlen(buf, PAGE_SIZE);
+}
+
 DEVICE_ATTR(position,0444,show_position,NULL);
+DEVICE_ATTR(action,0644,show_action,store_action);
 
 #define MPC52xx_GPT_MODE_DISABLED 0
 #define MPC52xx_GPT_MODE_INCAPT   1
@@ -57,6 +83,7 @@ static void  pwm_done(struct mpc52xx_gpt *gpt)
 
 static void motorek_action(struct motorek *m, int action_permile)
 {
+       m->action = action_permile;
        if (action_permile >= 0) {
                pwm_width(m->pwmb, 0);
                pwm_width(m->pwmf, +action_permile*PWM_PERIOD/1000);
@@ -70,9 +97,7 @@ static int __devinit motorek_init(struct motorek *m)
 {
        pwm_init(m->pwmf);
        pwm_init(m->pwmb);
-/*     motorek_action(m, +45); */
-       pwm_width(m->pwmb, 500);
-       pwm_width(m->pwmf, 500);
+       //motorek_action(m, +0);
        return 0;
 }
 
@@ -90,16 +115,26 @@ static irqreturn_t motorek_irq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/* mpc5200 device tree match tables */
-static struct of_device_id mpc5200_gpt_ids[] __initdata = {
-       { .compatible = "fsl,mpc5200-gpt", },
-       { .compatible = "mpc5200-gpt", },
-       {}
-};
-
-static int __devinit motorek_probe(struct platform_device *dev)
+struct mpc52xx_gpt __iomem *iomap_gpt_by_phandle(const phandle *phandle)
 {
        struct device_node *np;
+       struct mpc52xx_gpt __iomem *gpt;
+
+       if (!phandle)
+               return NULL;
+
+       np = of_find_node_by_phandle(*phandle);
+       if (!np)
+               return NULL;
+       gpt = of_iomap(np, 0);
+       of_node_put(np);
+       return gpt;
+}
+
+static int __devinit motorek_probe(struct of_device* dev,
+                                  const struct of_device_id *match)
+{
+       struct device_node *dn = dev->node;
        struct motorek *m;
        int err;
 
@@ -107,23 +142,9 @@ static int __devinit motorek_probe(struct platform_device *dev)
        if (!m)
                return -ENOMEM;
 
-       for_each_matching_node(np, mpc5200_gpt_ids) {
-               const void *prop;
-               int i;
-               
-               prop = of_get_property(np, "cell-index", NULL);
-               if (prop) {
-                       i = *(u32 *)prop;
-                       switch (i) {
-                       case 1:
-                               m->pwmf = of_iomap(np, 0);
-                               break;
-                       case 2:
-                               m->pwmb = of_iomap(np, 0);
-                               break;
-                       }
-               }
-       }
+       m->pwmf = iomap_gpt_by_phandle(of_get_property(dn, "pwmf", NULL));
+       m->pwmb = iomap_gpt_by_phandle(of_get_property(dn, "pwmb", NULL));
+       
        if (!m->pwmf || !m->pwmb) {
                printk(KERN_ERR "%s() mmap failed\n", __func__);
                return -ENXIO;
@@ -141,6 +162,9 @@ static int __devinit motorek_probe(struct platform_device *dev)
        platform_set_drvdata(dev, m);
 
        err = device_create_file(&dev->dev,&dev_attr_position);
+       if (err)
+               return err;
+       err = device_create_file(&dev->dev,&dev_attr_action);
        if (err)
                return err;
 
@@ -149,7 +173,7 @@ static int __devinit motorek_probe(struct platform_device *dev)
        return 0;
 }
 
-static int __devexit motorek_remove(struct platform_device *dev)
+static int __devexit motorek_remove(struct of_device* dev)
 {
        struct motorek *m;
        m = platform_get_drvdata(dev);
@@ -160,41 +184,49 @@ static int __devexit motorek_remove(struct platform_device *dev)
        return 0;
 }
 
-
-
-static struct platform_driver motorek_driver = {
+static struct of_device_id motorek_match[] = {
+       { .type = "motorek", },
+       {},
+};
+static struct of_platform_driver motorek_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "motorek",
+       .match_table    = motorek_match,
        .probe          = motorek_probe,
        .remove         = __devexit_p(motorek_remove),
-       .driver         = {
-               .name   = "motorek",
-               .owner  = THIS_MODULE,
-       },
 };
 
 
-static struct platform_device *motorek_pdev;
-
 static int __init motorek_init_module(void)
 {
        int ret;
-       motorek_pdev = platform_device_alloc("motorek", 0);
-       if (!motorek_pdev)
-               return -ENOMEM;
-       ret = platform_device_add(motorek_pdev);
-       if (ret) {
-               platform_device_put(motorek_pdev);
-               return ret;
-       }
+       struct of_device *dev;
+       struct device_node *dn;
+
+       for_each_node_by_type(dn, "motorek") {
+               if (!of_find_device_by_node(dn)) {
+                       dev = of_platform_device_create(dn, "motorek", NULL);
+                       if (!dev)
+                               return -ENOMEM;
+               }
+       };
 
-       ret = platform_driver_register(&motorek_driver);
-       return 0;
+       ret = of_register_platform_driver(&motorek_driver);
+       return ret;
 }
 module_init(motorek_init_module);
 
 static void __exit motorek_exit_module(void)
 {
-       platform_device_unregister(motorek_pdev);
-       platform_driver_unregister(&motorek_driver);
+       struct of_device *dev;
+       struct device_node *dn;
+
+       for_each_node_by_type(dn, "motorek") {
+               while ((dev = of_find_device_by_node(dn))) {
+                       of_device_unregister(dev);
+               }
+       }
+       of_unregister_platform_driver(&motorek_driver);
 }
 module_exit(motorek_exit_module);