[RFC] vibrator redesign

7 messages Options
Embed this post
Permalink
Michael Trimarchi

[RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
Hi,

this is a possible redisign. Now I will move the hdq to the timer 2
instead of 3

Michael

GTA02-vibrator rewrite. Maybe GTA01 use a pin instead of TOUT3, I will check

Not-yet-signed-off: Michael Trimarchi <[hidden email]>

diff --git a/drivers/leds/leds-gta02-vibrator.c b/drivers/leds/leds-gta02-vibrator.c
index 138af6d..e99f4eb 100644
--- a/drivers/leds/leds-gta02-vibrator.c
+++ b/drivers/leds/leds-gta02-vibrator.c
@@ -2,6 +2,7 @@
  * LED driver for the vibrator of the Openmoko GTA01/GTA02 GSM Phones
  *
  * (C) 2006-2008 by Openmoko, Inc.
+ * (C) 2009 Michael Trimarchi <[hidden email]>
  * Author: Harald Welte <[hidden email]>
  * All rights reserved.
  *
@@ -19,107 +20,88 @@
 #include <linux/leds.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <plat/pwm.h>
+#include <linux/pwm.h>
 #include <mach/regs-gpio.h>
 #include <mach/gpio-fns.h>
 #include <plat/regs-timer.h>
 #include <linux/gta02-vibrator.h>
 
-#define COUNTER 64
-
-static struct gta02_vib_priv {
+static struct gta02_vibrator_priv {
  struct led_classdev cdev;
- unsigned int gpio;
- spinlock_t lock;
- unsigned int has_pwm;
- struct s3c2410_pwm pwm;
-
- unsigned long vib_gpio_pin; /* which pin to meddle with */
- uint8_t vib_pwm; /* 0 = OFF -- will ensure GPIO deasserted and stop FIQ */
- uint8_t vib_pwm_latched;
- uint8_t fiq_count;
-
- struct gta02_vib_platform_data *pdata;
-} gta02_vib_priv;
+ struct pwm_device *pwm;
+ int period_ns;
+ enum led_brightness value;
+} gta02_vibrator_priv;
 
-int gta02_vibrator_fiq_handler(void)
+static void gta02_vibrator_set(struct led_classdev *led_cdev,
+      enum led_brightness value)
 {
- gta02_vib_priv.fiq_count++;
-
- if (!gta02_vib_priv.vib_pwm_latched && !gta02_vib_priv.vib_pwm)
- /* idle */
- return 0;
-
- if (gta02_vib_priv.fiq_count == gta02_vib_priv.vib_pwm_latched)
- s3c2410_gpio_setpin(gta02_vib_priv.vib_gpio_pin, 0);
-
- if (gta02_vib_priv.fiq_count)
- return 1;
-
- gta02_vib_priv.vib_pwm_latched = gta02_vib_priv.vib_pwm;
- if (gta02_vib_priv.vib_pwm_latched)
- s3c2410_gpio_setpin(gta02_vib_priv.vib_gpio_pin, 1);
-
- return 1;
+ struct gta02_vibrator_priv *gta02_vib;
+ int duty_ns;
+
+        /* update the duty cycle for the *next* period */
+        gta02_vib = container_of(led_cdev, struct gta02_vibrator_priv, cdev);
+
+ /*
+ * value == 255 -> 99% duty cycle (full power)
+ * value == 128 -> 50% duty cycle (medium power)
+ * value == 0 -> 0% duty cycle (zero power)
+ */
+ duty_ns = gta02_vib->period_ns * 255 / value;
+ if (value) {
+ pwm_config(gta02_vib->pwm, duty_ns, gta02_vib->period_ns);
+ pwm_enable(gta02_vib->pwm);
+ } else
+ pwm_disable(gta02_vib->pwm);
+
+ gta02_vib->value = value;
 }
 
-static void gta02_vib_vib_set(struct led_classdev *led_cdev,
- enum led_brightness value)
+static int gta02_vibrator_init_hw(struct gta02_vibrator_priv *gta02_vib)
 {
- gta02_vib_priv.vib_pwm = value; /* set it for FIQ */
- gta02_vib_priv.pdata->kick_fiq(); /* start up FIQs if not already going */
-}
+ int ret = 0;
 
-static struct gta02_vib_priv gta02_vib_led = {
- .cdev = {
- .name = "gta02:vibrator",
- .brightness_set = gta02_vib_vib_set,
- },
-};
-
-static int gta02_vib_init_hw(struct gta02_vib_priv *vp)
-{
- int rc;
-
- rc = s3c2410_pwm_init(&vp->pwm);
- if (rc)
- return rc;
-
- vp->pwm.timerid = PWM3;
- /* use same prescaler as arch/arm/plat-s3c24xx/time.c */
- vp->pwm.prescaler = (6 - 1) / 2;
- vp->pwm.divider = S3C2410_TCFG1_MUX3_DIV2;
- vp->pwm.counter = COUNTER;
- vp->pwm.comparer = COUNTER;
+ gta02_vib->pwm = pwm_request(3, "vibrator-gta02");
+ if (!gta02_vib->pwm) {
+ ret = -EINVAL;
+ goto bail;
+ }
 
- rc = s3c2410_pwm_enable(&vp->pwm);
- if (rc)
- return rc;
+ ret = pwm_config(gta02_vib->pwm, 0, gta02_vib->period_ns);
+ if (ret)
+ goto bail;
 
- s3c2410_pwm_start(&vp->pwm);
+ gta02_vib->value = 0;
 
  return 0;
+bail:
+ return ret;
 }
 
 #ifdef CONFIG_PM
-static int gta02_vib_suspend(struct platform_device *dev, pm_message_t state)
+static int gta02_vibrator_suspend(struct platform_device *dev,
+  pm_message_t state)
 {
- led_classdev_suspend(>a02_vib_led.cdev);
- if (gta02_vib_priv.pdata)
- gta02_vib_priv.pdata->disable_fiq();
+ struct gta02_vibrator_priv *gta02_vib = platform_get_drvdata(dev);
+
+ if (!gta02_vib->pwm)
+ pwm_free(gta02_vib->pwm);
+
+ gta02_vib->pwm = NULL;
+
+ led_classdev_suspend(>a02_vib->cdev);
+
  return 0;
 }
 
-static int gta02_vib_resume(struct platform_device *dev)
+static int gta02_vibrator_resume(struct platform_device *dev)
 {
- struct gta02_vib_priv *vp = platform_get_drvdata(dev);
+ struct gta02_vibrator_priv *gta02_vib = platform_get_drvdata(dev);
 
- if (vp->has_pwm)
- gta02_vib_init_hw(vp);
+ if (!gta02_vib->pwm)
+ gta02_vibrator_init_hw(gta02_vib);
 
- led_classdev_resume(>a02_vib_led.cdev);
- if (gta02_vib_priv.pdata)
- gta02_vib_priv.pdata->enable_fiq();
+ led_classdev_resume(>a02_vib->cdev);
 
  return 0;
 }
@@ -128,64 +110,63 @@ static int gta02_vib_resume(struct platform_device *dev)
 #define gta02_vib_resume NULL
 #endif /* CONFIG_PM */
 
-static int __init gta02_vib_probe(struct platform_device *pdev)
+static int __init gta02_vibrator_probe(struct platform_device *pdev)
 {
- struct resource *r;
+ struct gta02_vibrator_priv *gta02_vib;
+ struct gta02_vibrator_platform_data *pdata = platform_get_drvdata(pdev);
 
- r = platform_get_resource(pdev, 0, 0);
- if (!r || !r->start)
- return -EIO;
+        if (!pdata)
+                return -ENODEV;
 
- gta02_vib_led.gpio = r->start;
+ gta02_vib = kmalloc(sizeof(gta02_vibrator_priv), GFP_KERNEL);
+ if (!gta02_vib)
+ return -ENOMEM;
 
- gta02_vib_priv.pdata = pdev->dev.platform_data;
- platform_set_drvdata(pdev, >a02_vib_led);
+ gta02_vib->period_ns = pdata->period_ns;
+ gta02_vib->cdev.name = "gta02:vibrator";
+ gta02_vib->cdev.brightness_set = gta02_vibrator_set;
 
- s3c2410_gpio_setpin(gta02_vib_led.gpio, 0); /* off */
- s3c2410_gpio_cfgpin(gta02_vib_led.gpio, S3C2410_GPIO_OUTPUT);
- /* safe, kmalloc'd copy needed for FIQ ISR */
- gta02_vib_priv.vib_gpio_pin = gta02_vib_led.gpio;
- gta02_vib_priv.vib_pwm = 0; /* off */
- spin_lock_init(>a02_vib_led.lock);
+ platform_set_drvdata(pdev, >a02_vib);
 
- return led_classdev_register(&pdev->dev, >a02_vib_led.cdev);
+ return led_classdev_register(&pdev->dev, >a02_vib->cdev);
 }
 
-static int gta02_vib_remove(struct platform_device *pdev)
+static int gta02_vibrator_remove(struct platform_device *pdev)
 {
- gta02_vib_priv.vib_pwm = 0; /* off */
- /* would only need kick if already off so no kick needed */
+ struct gta02_vibrator_priv *gta02_vib = platform_get_drvdata(pdev);
 
- if (gta02_vib_led.has_pwm)
- s3c2410_pwm_disable(>a02_vib_led.pwm);
+ if (!gta02_vib->pwm)
+ pwm_free(gta02_vib->pwm);
 
- led_classdev_unregister(>a02_vib_led.cdev);
+ led_classdev_unregister(>a02_vib->cdev);
+ kfree(gta02_vib);
 
  return 0;
 }
 
-static struct platform_driver gta02_vib_driver = {
- .probe = gta02_vib_probe,
- .remove = gta02_vib_remove,
- .suspend = gta02_vib_suspend,
- .resume = gta02_vib_resume,
+static struct platform_driver gta02_vibrator_driver = {
+ .probe = gta02_vibrator_probe,
+ .remove = gta02_vibrator_remove,
+ .suspend = gta02_vibrator_suspend,
+ .resume = gta02_vibrator_resume,
  .driver = {
  .name = "gta02-vibrator",
  },
 };
 
-static int __init gta02_vib_init(void)
+static int __init gta02_vibrator_init(void)
 {
- return platform_driver_register(>a02_vib_driver);
+ return platform_driver_register(>a02_vibrator_driver);
 }
-module_init(gta02_vib_init);
+module_init(gta02_vibrator_init);
 
-static void __exit gta02_vib_exit(void)
+static void __exit gta02_vibrator_exit(void)
 {
- platform_driver_unregister(>a02_vib_driver);
+ platform_driver_unregister(>a02_vibrator_driver);
 }
-module_exit(gta02_vib_exit);
+module_exit(gta02_vibrator_exit);
 
-MODULE_AUTHOR("Harald Welte <[hidden email]>");
+MODULE_AUTHOR("Harald Welte <[hidden email]>"
+       "Michael Trimarchi <[hidden email]>");
 MODULE_DESCRIPTION("Openmoko Freerunner vibrator driver");
 MODULE_LICENSE("GPL");
Michael Trimarchi

Re: [RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
Hi

+    duty_ns = gta02_vib->period_ns * 255 / value;

This is wrong but I don't test it but just compile.

+    if (value) {
+        pwm_config(gta02_vib->pwm, duty_ns, gta02_vib->period_ns);
+        pwm_enable(gta02_vib->pwm);
+    } else
+        pwm_disable(gta02_vib->pwm);

There is a semplification of the platform data too that contains only
the period_ns.


Michael

Lars-Peter Clausen

Re: [RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
In reply to this post by Michael Trimarchi
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Michael Trimarchi wrote:
> Hi,
>
> this is a possible redisign. Now I will move the hdq to the timer 2
> instead of 3
>
> Michael
Hi Michael

Well, as I said, it's much more easier to simply use the leds_pwm driver.

- - Lars
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkrtd8gACgkQBX4mSR26RiOsSwCfeEj0l26JsJRinZJRUYuVe5Ty
/X4AoIYBEQynuO3eaCpownlPqvC//btL
=ObsR
-----END PGP SIGNATURE-----


Michael 'Mickey' Lauer-2

Re: [RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
In reply to this post by Michael Trimarchi
Will this bring back PWM for the vibrator on 02?

--
:M:


Lars-Peter Clausen

Re: [RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Michael 'Mickey' Lauer wrote:
> Will this bring back PWM for the vibrator on 02?
>
yes
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkrtgL8ACgkQBX4mSR26RiPOrgCfYn7RUJidRPu8vyTay1MtdE/4
7akAn13oBEbtWMmTY1rtdGG1VOMIQ7DH
=/5Ev
-----END PGP SIGNATURE-----


Michael Trimarchi

Re: [RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
In reply to this post by Michael Trimarchi
Ok ,  just few changes. Now I'm working on hdq redisign

Michael

Android openmoko message
Lars-Peter Clausen <[hidden email]> ha scritto:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Michael Trimarchi wrote:
>> Hi,
>>
>> this is a possible redisign. Now I will move the hdq to the timer 2
>> instead of 3
>>
>> Michael
> Hi Michael
>
> Well, as I said, it's much more easier to simply use the leds_pwm driver.
>
> - - Lars
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkrtd8gACgkQBX4mSR26RiOsSwCfeEj0l26JsJRinZJRUYuVe5Ty
> /X4AoIYBEQynuO3eaCpownlPqvC//btL
> =ObsR
> -----END PGP SIGNATURE-----
>
>



----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.


Michael Trimarchi

Re: [RFC] vibrator redesign

Reply Threaded More More options
Print post
Permalink
In reply to this post by Lars-Peter Clausen
Lars-Peter Clausen wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Michael Trimarchi wrote:
>  
>> Hi,
>>
>> this is a possible redisign. Now I will move the hdq to the timer 2
>> instead of 3
>>
>> Michael
>>    
> Hi Michael
>
> Well, as I said, it's much more easier to simply use the leds_pwm driver.
>  
Look at the code, I have done the same driver :)...

Michael

> - - Lars
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkrtd8gACgkQBX4mSR26RiOsSwCfeEj0l26JsJRinZJRUYuVe5Ty
> /X4AoIYBEQynuO3eaCpownlPqvC//btL
> =ObsR
> -----END PGP SIGNATURE-----
>
>
>