Merge tag 'asoc-v5.3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-microblaze.git] / sound / usb / line6 / pod.c
index 200ae53..ee4c9d2 100644 (file)
        Stages of POD startup procedure
 */
 enum {
-       POD_STARTUP_INIT = 1,
        POD_STARTUP_VERSIONREQ,
-       POD_STARTUP_WORKQUEUE,
        POD_STARTUP_SETUP,
-       POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
+       POD_STARTUP_DONE,
 };
 
 enum {
@@ -59,12 +57,6 @@ struct usb_line6_pod {
        /* Instrument monitor level */
        int monitor_level;
 
-       /* Timer for device initialization */
-       struct timer_list startup_timer;
-
-       /* Work handler for device initialization */
-       struct work_struct startup_work;
-
        /* Current progress in startup procedure */
        int startup_progress;
 
@@ -78,6 +70,8 @@ struct usb_line6_pod {
        int device_id;
 };
 
+#define line6_to_pod(x)                container_of(x, struct usb_line6_pod, line6)
+
 #define POD_SYSEX_CODE 3
 
 /* *INDENT-OFF* */
@@ -169,10 +163,6 @@ static const char pod_version_header[] = {
        0xf2, 0x7e, 0x7f, 0x06, 0x02
 };
 
-/* forward declarations: */
-static void pod_startup2(struct timer_list *t);
-static void pod_startup3(struct usb_line6_pod *pod);
-
 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
                                    int size)
 {
@@ -185,14 +175,17 @@ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
 */
 static void line6_pod_process_message(struct usb_line6 *line6)
 {
-       struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
+       struct usb_line6_pod *pod = line6_to_pod(line6);
        const unsigned char *buf = pod->line6.buffer_message;
 
        if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
                pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
                pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) |
                                 (int) buf[10];
-               pod_startup3(pod);
+               if (pod->startup_progress == POD_STARTUP_VERSIONREQ) {
+                       pod->startup_progress = POD_STARTUP_SETUP;
+                       schedule_delayed_work(&line6->startup_work, 0);
+               }
                return;
        }
 
@@ -277,47 +270,27 @@ static ssize_t device_id_show(struct device *dev,
        context). After the last one has finished, the device is ready to use.
 */
 
-static void pod_startup1(struct usb_line6_pod *pod)
-{
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
-
-       /* delay startup procedure: */
-       line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2);
-}
-
-static void pod_startup2(struct timer_list *t)
-{
-       struct usb_line6_pod *pod = from_timer(pod, t, startup_timer);
-       struct usb_line6 *line6 = &pod->line6;
-
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
-
-       /* request firmware version: */
-       line6_version_request_async(line6);
-}
-
-static void pod_startup3(struct usb_line6_pod *pod)
-{
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
-
-       /* schedule work for global work queue: */
-       schedule_work(&pod->startup_work);
-}
-
-static void pod_startup4(struct work_struct *work)
+static void pod_startup(struct usb_line6 *line6)
 {
-       struct usb_line6_pod *pod =
-           container_of(work, struct usb_line6_pod, startup_work);
-       struct usb_line6 *line6 = &pod->line6;
-
-       CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
-
-       /* serial number: */
-       line6_read_serial_number(&pod->line6, &pod->serial_number);
-
-       /* ALSA audio interface: */
-       if (snd_card_register(line6->card))
-               dev_err(line6->ifcdev, "Failed to register POD card.\n");
+       struct usb_line6_pod *pod = line6_to_pod(line6);
+
+       switch (pod->startup_progress) {
+       case POD_STARTUP_VERSIONREQ:
+               /* request firmware version: */
+               line6_version_request_async(line6);
+               break;
+       case POD_STARTUP_SETUP:
+               /* serial number: */
+               line6_read_serial_number(&pod->line6, &pod->serial_number);
+
+               /* ALSA audio interface: */
+               if (snd_card_register(line6->card))
+                       dev_err(line6->ifcdev, "Failed to register POD card.\n");
+               pod->startup_progress = POD_STARTUP_DONE;
+               break;
+       default:
+               break;
+       }
 }
 
 /* POD special files: */
@@ -353,7 +326,7 @@ static int snd_pod_control_monitor_get(struct snd_kcontrol *kcontrol,
                                       struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
+       struct usb_line6_pod *pod = line6_to_pod(line6pcm->line6);
 
        ucontrol->value.integer.value[0] = pod->monitor_level;
        return 0;
@@ -364,7 +337,7 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
                                       struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
-       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
+       struct usb_line6_pod *pod = line6_to_pod(line6pcm->line6);
 
        if (ucontrol->value.integer.value[0] == pod->monitor_level)
                return 0;
@@ -386,17 +359,6 @@ static const struct snd_kcontrol_new pod_control_monitor = {
        .put = snd_pod_control_monitor_put
 };
 
-/*
-       POD device disconnected.
-*/
-static void line6_pod_disconnect(struct usb_line6 *line6)
-{
-       struct usb_line6_pod *pod = (struct usb_line6_pod *)line6;
-
-       del_timer_sync(&pod->startup_timer);
-       cancel_work_sync(&pod->startup_work);
-}
-
 /*
         Try to init POD device.
 */
@@ -404,13 +366,10 @@ static int pod_init(struct usb_line6 *line6,
                    const struct usb_device_id *id)
 {
        int err;
-       struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
+       struct usb_line6_pod *pod = line6_to_pod(line6);
 
        line6->process_message = line6_pod_process_message;
-       line6->disconnect = line6_pod_disconnect;
-
-       timer_setup(&pod->startup_timer, NULL, 0);
-       INIT_WORK(&pod->startup_work, pod_startup4);
+       line6->startup = pod_startup;
 
        /* create sysfs entries: */
        err = snd_card_add_dev_attr(line6->card, &pod_dev_attr_group);
@@ -443,7 +402,8 @@ static int pod_init(struct usb_line6 *line6,
                pod->monitor_level = POD_SYSTEM_INVALID;
 
                /* initiate startup procedure: */
-               pod_startup1(pod);
+               schedule_delayed_work(&line6->startup_work,
+                                     msecs_to_jiffies(POD_STARTUP_DELAY));
        }
 
        return 0;