ALSA: line6: variax: Rewrite complex timer & work combo with a delayed work
Variax driver had a very complex and staged startup sequence using multiple timers and a work. This patch simplifies the procedure to a single delayed work. Now the startup stage consists of: - VARIAX_STARTUP_VERSIONREQ: requesting the version and the message handler raises up to the next stage upon receiving the reply. The request is repeated until a reply arrives. - VARIAX_STARTUP_ACTIVATE: does activation, and queue for the next stage. - VARIAX_STARTUP_SETUP: registers the card. Signed-off-by: Takashi Iwai <tiwai@suse.de>alistair/sunxi64-5.4-dsi
parent
a91c1da77c
commit
6ea53391c0
|
@ -26,13 +26,9 @@
|
||||||
Stages of Variax startup procedure
|
Stages of Variax startup procedure
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
VARIAX_STARTUP_INIT = 1,
|
|
||||||
VARIAX_STARTUP_VERSIONREQ,
|
VARIAX_STARTUP_VERSIONREQ,
|
||||||
VARIAX_STARTUP_WAIT,
|
|
||||||
VARIAX_STARTUP_ACTIVATE,
|
VARIAX_STARTUP_ACTIVATE,
|
||||||
VARIAX_STARTUP_WORKQUEUE,
|
|
||||||
VARIAX_STARTUP_SETUP,
|
VARIAX_STARTUP_SETUP,
|
||||||
VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -47,13 +43,6 @@ struct usb_line6_variax {
|
||||||
/* Buffer for activation code */
|
/* Buffer for activation code */
|
||||||
unsigned char *buffer_activate;
|
unsigned char *buffer_activate;
|
||||||
|
|
||||||
/* Handler for device initialization */
|
|
||||||
struct work_struct startup_work;
|
|
||||||
|
|
||||||
/* Timers for device initialization */
|
|
||||||
struct timer_list startup_timer1;
|
|
||||||
struct timer_list startup_timer2;
|
|
||||||
|
|
||||||
/* Current progress in startup procedure */
|
/* Current progress in startup procedure */
|
||||||
int startup_progress;
|
int startup_progress;
|
||||||
};
|
};
|
||||||
|
@ -81,11 +70,6 @@ static const char variax_activate[] = {
|
||||||
0xf7
|
0xf7
|
||||||
};
|
};
|
||||||
|
|
||||||
/* forward declarations: */
|
|
||||||
static void variax_startup2(struct timer_list *t);
|
|
||||||
static void variax_startup4(struct timer_list *t);
|
|
||||||
static void variax_startup5(struct timer_list *t);
|
|
||||||
|
|
||||||
static void variax_activate_async(struct usb_line6_variax *variax, int a)
|
static void variax_activate_async(struct usb_line6_variax *variax, int a)
|
||||||
{
|
{
|
||||||
variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
|
variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = a;
|
||||||
|
@ -100,74 +84,30 @@ static void variax_activate_async(struct usb_line6_variax *variax, int a)
|
||||||
context). After the last one has finished, the device is ready to use.
|
context). After the last one has finished, the device is ready to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void variax_startup1(struct usb_line6_variax *variax)
|
static void variax_startup(struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
|
struct usb_line6_variax *variax = (struct usb_line6_variax *)line6;
|
||||||
|
|
||||||
/* delay startup procedure: */
|
switch (variax->startup_progress) {
|
||||||
line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
|
case VARIAX_STARTUP_VERSIONREQ:
|
||||||
variax_startup2);
|
/* repeat request until getting the response */
|
||||||
}
|
schedule_delayed_work(&line6->startup_work,
|
||||||
|
msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
|
||||||
static void variax_startup2(struct timer_list *t)
|
/* request firmware version: */
|
||||||
{
|
line6_version_request_async(line6);
|
||||||
struct usb_line6_variax *variax = from_timer(variax, t, startup_timer1);
|
break;
|
||||||
struct usb_line6 *line6 = &variax->line6;
|
case VARIAX_STARTUP_ACTIVATE:
|
||||||
|
/* activate device: */
|
||||||
/* schedule another startup procedure until startup is complete: */
|
variax_activate_async(variax, 1);
|
||||||
if (variax->startup_progress >= VARIAX_STARTUP_LAST)
|
variax->startup_progress = VARIAX_STARTUP_SETUP;
|
||||||
return;
|
schedule_delayed_work(&line6->startup_work,
|
||||||
|
msecs_to_jiffies(VARIAX_STARTUP_DELAY4));
|
||||||
variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
|
break;
|
||||||
line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
|
case VARIAX_STARTUP_SETUP:
|
||||||
variax_startup2);
|
/* ALSA audio interface: */
|
||||||
|
snd_card_register(variax->line6.card);
|
||||||
/* request firmware version: */
|
break;
|
||||||
line6_version_request_async(line6);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void variax_startup3(struct usb_line6_variax *variax)
|
|
||||||
{
|
|
||||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
|
|
||||||
|
|
||||||
/* delay startup procedure: */
|
|
||||||
line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
|
|
||||||
variax_startup4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void variax_startup4(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct usb_line6_variax *variax = from_timer(variax, t, startup_timer2);
|
|
||||||
|
|
||||||
CHECK_STARTUP_PROGRESS(variax->startup_progress,
|
|
||||||
VARIAX_STARTUP_ACTIVATE);
|
|
||||||
|
|
||||||
/* activate device: */
|
|
||||||
variax_activate_async(variax, 1);
|
|
||||||
line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
|
|
||||||
variax_startup5);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void variax_startup5(struct timer_list *t)
|
|
||||||
{
|
|
||||||
struct usb_line6_variax *variax = from_timer(variax, t, startup_timer2);
|
|
||||||
|
|
||||||
CHECK_STARTUP_PROGRESS(variax->startup_progress,
|
|
||||||
VARIAX_STARTUP_WORKQUEUE);
|
|
||||||
|
|
||||||
/* schedule work for global work queue: */
|
|
||||||
schedule_work(&variax->startup_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void variax_startup6(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct usb_line6_variax *variax =
|
|
||||||
container_of(work, struct usb_line6_variax, startup_work);
|
|
||||||
|
|
||||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
|
|
||||||
|
|
||||||
/* ALSA audio interface: */
|
|
||||||
snd_card_register(variax->line6.card);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -186,11 +126,19 @@ static void line6_variax_process_message(struct usb_line6 *line6)
|
||||||
case LINE6_SYSEX_BEGIN:
|
case LINE6_SYSEX_BEGIN:
|
||||||
if (memcmp(buf + 1, variax_init_version + 1,
|
if (memcmp(buf + 1, variax_init_version + 1,
|
||||||
sizeof(variax_init_version) - 1) == 0) {
|
sizeof(variax_init_version) - 1) == 0) {
|
||||||
variax_startup3(variax);
|
if (variax->startup_progress >= VARIAX_STARTUP_ACTIVATE)
|
||||||
|
break;
|
||||||
|
variax->startup_progress = VARIAX_STARTUP_ACTIVATE;
|
||||||
|
cancel_delayed_work(&line6->startup_work);
|
||||||
|
schedule_delayed_work(&line6->startup_work,
|
||||||
|
msecs_to_jiffies(VARIAX_STARTUP_DELAY3));
|
||||||
} else if (memcmp(buf + 1, variax_init_done + 1,
|
} else if (memcmp(buf + 1, variax_init_done + 1,
|
||||||
sizeof(variax_init_done) - 1) == 0) {
|
sizeof(variax_init_done) - 1) == 0) {
|
||||||
/* notify of complete initialization: */
|
/* notify of complete initialization: */
|
||||||
variax_startup4(&variax->startup_timer2);
|
if (variax->startup_progress >= VARIAX_STARTUP_SETUP)
|
||||||
|
break;
|
||||||
|
cancel_delayed_work(&line6->startup_work);
|
||||||
|
schedule_delayed_work(&line6->startup_work, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -203,10 +151,6 @@ static void line6_variax_disconnect(struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
struct usb_line6_variax *variax = (struct usb_line6_variax *)line6;
|
struct usb_line6_variax *variax = (struct usb_line6_variax *)line6;
|
||||||
|
|
||||||
del_timer(&variax->startup_timer1);
|
|
||||||
del_timer(&variax->startup_timer2);
|
|
||||||
cancel_work_sync(&variax->startup_work);
|
|
||||||
|
|
||||||
kfree(variax->buffer_activate);
|
kfree(variax->buffer_activate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,10 +165,7 @@ static int variax_init(struct usb_line6 *line6,
|
||||||
|
|
||||||
line6->process_message = line6_variax_process_message;
|
line6->process_message = line6_variax_process_message;
|
||||||
line6->disconnect = line6_variax_disconnect;
|
line6->disconnect = line6_variax_disconnect;
|
||||||
|
line6->startup = variax_startup;
|
||||||
timer_setup(&variax->startup_timer1, NULL, 0);
|
|
||||||
timer_setup(&variax->startup_timer2, NULL, 0);
|
|
||||||
INIT_WORK(&variax->startup_work, variax_startup6);
|
|
||||||
|
|
||||||
/* initialize USB buffers: */
|
/* initialize USB buffers: */
|
||||||
variax->buffer_activate = kmemdup(variax_activate,
|
variax->buffer_activate = kmemdup(variax_activate,
|
||||||
|
@ -239,7 +180,8 @@ static int variax_init(struct usb_line6 *line6,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* initiate startup procedure: */
|
/* initiate startup procedure: */
|
||||||
variax_startup1(variax);
|
schedule_delayed_work(&line6->startup_work,
|
||||||
|
msecs_to_jiffies(VARIAX_STARTUP_DELAY1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue