]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - sound/soc/soc-jack.c
ASoC: Use delayed work for debounce of GPIO based jacks
[net-next-2.6.git] / sound / soc / soc-jack.c
index 29159e1781d0edbc681a8120865323171a7a4906..8a0a9205b1e785bf92d6ddd773b0a70cc7cf568d 100644 (file)
  * Returns zero if successful, or a negative error code on failure.
  * On success jack will be initialised.
  */
-int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
+int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
                     struct snd_soc_jack *jack)
 {
-       jack->card = card;
+       jack->codec = codec;
        INIT_LIST_HEAD(&jack->pins);
        BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
 
-       return snd_jack_new(card->codec->card, id, type, &jack->jack);
+       return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
 }
 EXPORT_SYMBOL_GPL(snd_soc_jack_new);
 
@@ -67,7 +67,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
        if (!jack)
                return;
 
-       codec = jack->card->codec;
+       codec = jack->codec;
 
        mutex_lock(&codec->mutex);
 
@@ -188,9 +188,6 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
        int enable;
        int report;
 
-       if (gpio->debounce_time > 0)
-               mdelay(gpio->debounce_time);
-
        enable = gpio_get_value(gpio->gpio);
        if (gpio->invert)
                enable = !enable;
@@ -211,7 +208,8 @@ static irqreturn_t gpio_handler(int irq, void *data)
 {
        struct snd_soc_jack_gpio *gpio = data;
 
-       schedule_work(&gpio->work);
+       schedule_delayed_work(&gpio->work,
+                             msecs_to_jiffies(gpio->debounce_time));
 
        return IRQ_HANDLED;
 }
@@ -221,7 +219,7 @@ static void gpio_work(struct work_struct *work)
 {
        struct snd_soc_jack_gpio *gpio;
 
-       gpio = container_of(work, struct snd_soc_jack_gpio, work);
+       gpio = container_of(work, struct snd_soc_jack_gpio, work.work);
        snd_soc_jack_gpio_detect(gpio);
 }
 
@@ -262,13 +260,13 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
                if (ret)
                        goto err;
 
-               INIT_WORK(&gpios[i].work, gpio_work);
+               INIT_DELAYED_WORK(&gpios[i].work, gpio_work);
                gpios[i].jack = jack;
 
                ret = request_irq(gpio_to_irq(gpios[i].gpio),
                                gpio_handler,
                                IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                               jack->card->dev->driver->name,
+                               jack->codec->dev->driver->name,
                                &gpios[i]);
                if (ret)
                        goto err;
@@ -312,6 +310,7 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
                gpio_unexport(gpios[i].gpio);
 #endif
                free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]);
+               cancel_delayed_work_sync(&gpios[i].work);
                gpio_free(gpios[i].gpio);
                gpios[i].jack = NULL;
        }