From: Yusuf Caglar Akyuz <cag...@bilkon-kontrol.com.tr>

With the aid of simple sysfs interface driver, functionality can be
verified easily without writing a test program.

Signed-off-by: Yusuf Caglar Akyuz <cag...@bilkon-kontrol.com.tr>
---
 arch/arm/mach-davinci/pwm.c |   91 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-davinci/pwm.c b/arch/arm/mach-davinci/pwm.c
index ab66d82..f9aa5f4 100644
--- a/arch/arm/mach-davinci/pwm.c
+++ b/arch/arm/mach-davinci/pwm.c
@@ -47,6 +47,7 @@ struct pwm_davinci_device {
        davinci_pwmregsovly regs;
        wait_queue_head_t intr_wait;
        struct clk *pwm_clk;
+       int running;
 };
 
 char *dm644x_name[] = { "PWM0_CLK", "PWM1_CLK", "PWM2_CLK" };
@@ -338,6 +339,92 @@ static irqreturn_t pwm_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+#define PWM_FREQ 0x10000 / 48
+
+static ssize_t
+pwm_show(struct device *d, struct device_attribute *a, char *buf)
+{
+       struct pwm_davinci_device *pwm_dev;
+
+       pwm_dev = pwm_dev_get_by_minor(to_platform_device(d)->id);
+       
+       return sprintf(buf, "%s\n", pwm_dev->running == 1 ? "running" : 
"stopped");
+}
+static ssize_t
+pwm_start(struct device *d, struct device_attribute *a, const char *buf
+               , size_t count)
+{
+       struct pwm_davinci_device *pwm_dev;
+
+       if(count < 1)
+               return count;
+       
+       pwm_dev = pwm_dev_get_by_minor(to_platform_device(d)->id);
+       if(buf[0] == '1' && pwm_dev->running == 0) {
+               /* sample configuration */
+               pwm_dev->regs->per = PWM_FREQ;
+               pwm_dev->regs->ph1d = 0x0;
+               pwm_dev->regs->cfg |= 0x2;      
+               pwm_dev->intr_complete = 0;
+               pwm_dev->running = 1;
+               pwm_dev->regs->start = 0x1;
+       }
+
+       if(buf[0] == '0' && pwm_dev->running == 1) {
+               pwm_dev->regs->cfg &= 0xFFFFFFFC;
+               pwm_dev->running = 0;
+       }
+
+       return count;
+}
+static DEVICE_ATTR(control, S_IRUGO | S_IWUSR, pwm_show, pwm_start);
+
+static ssize_t
+duty_read(struct device *d, struct device_attribute *a, char *buf)
+{
+       struct pwm_davinci_device *pwm_dev;
+
+       pwm_dev = pwm_dev_get_by_minor(to_platform_device(d)->id);
+       
+       return sprintf(buf, "%d\n", pwm_dev->regs->ph1d);
+}
+static ssize_t
+duty_write(struct device *d, struct device_attribute *a, const char *buf
+               , size_t count)
+{
+       struct pwm_davinci_device *pwm_dev;     
+       int val = 0;
+
+       pwm_dev = pwm_dev_get_by_minor(to_platform_device(d)->id);
+       
+       if(count == 1)
+               val = (buf[0] - 48);
+       if(count == 2)
+               val = (buf[0] - 48) * 10 + (buf[1] - 48);
+       if(count == 3)
+               val = (buf[0] - 48) * 100 + (buf[1] - 48) * 10 + (buf[2] - 48);
+       
+       if(val < 256)
+               pwm_dev->regs->ph1d = val * (PWM_FREQ / 256);
+       else
+               pwm_dev->regs->ph1d = PWM_FREQ;
+
+       return count;
+}
+static DEVICE_ATTR(duty, S_IRUGO | S_IWUSR, duty_read, duty_write);
+
+static void create_sysfs_entries(struct device *dev)
+{
+       int status;
+       status = device_create_file(dev, &dev_attr_control);
+       status = device_create_file(dev, &dev_attr_duty);
+}
+static void remove_sysfs_entries(struct device *dev)
+{
+       device_remove_file(dev, &dev_attr_control);
+       device_remove_file(dev, &dev_attr_duty);
+}
+
 static int __init pwm_init(void)
 {
        int result;
@@ -454,6 +541,8 @@ static int __init pwm_init(void)
                        pwm_dev_array[j]->regs =
                            (davinci_pwmregsovly) IO_ADDRESS(DAVINCI_PWM0_BASE +
                                                             j * 0x400);
+                       pwm_dev_array[j]->running = 0;
+                       create_sysfs_entries(&pwm_device[j].dev);
                }
        }
        return 0;
@@ -467,6 +556,7 @@ static void __exit pwm_exit(void)
        if (pwm_class != NULL) {
                size = pwm_device_count * pwm_minor_count;
                for (i = 0; i < size; i++) {
+                       remove_sysfs_entries(&pwm_device[i].dev);
                        platform_device_unregister(&pwm_device[i]);
                        driver_unregister(&pwm_driver[i]);
                        devno = MKDEV(pwm_major, pwm_minor_start + i);
@@ -489,6 +579,7 @@ static void __exit pwm_exit(void)
                size = pwm_device_count * pwm_minor_count;
                unregister_chrdev_region(devno, size);
        }
+
 }
 
 module_init(pwm_init);
-- 
1.5.6


_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to