This is FIC GTA01 Vibrator driver with PWM functions.

       -Javi
diff -uprN -X dontdiff linux-2.6.22.5/drivers/leds/Kconfig linux-2.6.22.5.new/drivers/leds/Kconfig
--- linux-2.6.22.5/drivers/leds/Kconfig	2007-09-02 14:17:48.000000000 +0200
+++ linux-2.6.22.5.new/drivers/leds/Kconfig	2007-09-15 12:28:31.000000000 +0200
@@ -59,7 +59,7 @@ config LEDS_TOSA
 
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
-	depends on LEDS_CLASS && ARCH_S3C2410
+	depends on LEDS_CLASS && ARCH_S3C2410 && S3C2410_PWM
 	help
 	  This option enables support for LEDs connected to GPIO lines
 	  on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
diff -uprN -X dontdiff linux-2.6.22.5/drivers/leds/leds-gta01.c linux-2.6.22.5.new/drivers/leds/leds-gta01.c
--- linux-2.6.22.5/drivers/leds/leds-gta01.c	2007-09-02 14:17:48.000000000 +0200
+++ linux-2.6.22.5.new/drivers/leds/leds-gta01.c	2007-09-16 19:42:24.000000000 +0200
@@ -9,7 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * TODO: Implement PWM support for GTA01Bv4 and later
+ * Javi Roman <[EMAIL PROTECTED]>:
+ * 	Implement PWM support for GTA01Bv4 and later
  */
 
 #include <linux/kernel.h>
@@ -20,11 +21,17 @@
 #include <asm/mach-types.h>
 #include <asm/arch/gta01.h>
 
+#include <asm/arch/s3c2410-pwm.h>
+
+#define COUNTER 256
+
 struct gta01_vib_priv
 {
-	struct led_classdev	cdev;
+	struct led_classdev cdev;
 	unsigned int gpio;
+	struct mutex mutex;
 	unsigned int has_pwm;
+	struct s3c2410_pwm_t *pwm;
 };
 
 static inline struct gta01_vib_priv *pdev_to_vpriv(struct platform_device *dev)
@@ -37,14 +44,29 @@ static inline struct gta01_vib_priv *to_
 	return dev_get_drvdata(led_cdev->class_dev->dev);
 }
 
-static void gta01vib_vib_set(struct led_classdev *led_cdev, enum led_brightness value)
+static void gta01vib_vib_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
 {
 	struct gta01_vib_priv *vp = to_vpriv(led_cdev);
 
-	if (value)
-		s3c2410_gpio_setpin(vp->gpio, 1);
-	else
-		s3c2410_gpio_setpin(vp->gpio, 0);
+	/*
+ 	 * value == 255 -> 99% duty cycle (full voltage)
+ 	 * value == 128 -> 50% duty cycle (middle voltage)
+ 	 * value == 0 -> 0% duty cycle (zero voltage)
+ 	 */
+ 	mutex_lock(&vp->mutex);
+	if (vp->has_pwm) {
+			printk(KERN_INFO "updated duty cycle: %d\n", value);
+			s3c2410_pwm_duty_cycle(value, vp->pwm);
+			s3c2410_gpio_cfgpin(vp->gpio, S3C2410_GPB3_TOUT3);
+	} else {
+		if (value)
+			s3c2410_gpio_setpin(vp->gpio, 1);
+		else
+			s3c2410_gpio_setpin(vp->gpio, 0);
+	}
+
+	mutex_unlock(&vp->mutex);
 }
 
 static struct led_classdev gta01_vib_led = {
@@ -66,7 +88,23 @@ static int gta01vib_resume(struct platfo
 }
 #endif
 
-static int gta01vib_probe(struct platform_device *pdev)
+static void gta01vib_init_hw(struct platform_device *pdev)
+{
+	struct gta01_vib_priv *vp = pdev_to_vpriv(pdev);
+
+	vp->pwm->timerid= PWM3;
+	vp->pwm->prescaler = 0x0000;
+	vp->pwm->divider = S3C2410_TCFG1_MUX3_DIV8;
+	vp->pwm->counter = COUNTER;
+	vp->pwm->comparer = COUNTER;
+
+	s3c2410_pwm_enable(vp->pwm);
+	s3c2410_pwm_start(vp->pwm);
+	
+	return;
+}
+
+static int __init gta01vib_probe(struct platform_device *pdev)
 {
 	struct gta01_vib_priv *vp;
 	struct resource *r;
@@ -86,9 +124,23 @@ static int gta01vib_probe(struct platfor
 
 	vp->gpio = r->start;
 
-	if (vp->gpio == S3C2410_GPB3)
+	/* TOUT3 */
+	if (vp->gpio == S3C2410_GPB3) {
 		vp->has_pwm = 1;
 
+		vp->pwm = s3c2410_pwm_alloc();
+		if (!vp->pwm) {
+			printk(KERN_WARNING "PWM enabling failed.\n");
+			return -1;
+		}
+
+		gta01vib_init_hw(pdev);
+	}
+
+	mutex_init(&vp->mutex);
+
+	printk(KERN_INFO "GTA01 Vibrator Driver Initialized.\n");
+
 	return led_classdev_register(&pdev->dev, &gta01_vib_led);
 }
 
@@ -96,10 +148,17 @@ static int gta01vib_remove(struct platfo
 {
 	struct gta01_vib_priv *vp = pdev_to_vpriv(pdev);
 
+	if (vp->has_pwm) 
+		s3c2410_pwm_disable(vp->pwm);
+
 	led_classdev_unregister(&gta01_vib_led);
 	platform_set_drvdata(pdev, NULL);
 	kfree(vp);
 
+	mutex_destroy(&vp->mutex);
+
+	printk(KERN_INFO "GTA01 Vibrator Driver Unloaded\n");
+
 	return 0;
 }
 

Reply via email to