aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/fireworks/fireworks.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-04-25 09:45:01 -0400
committerTakashi Iwai <tiwai@suse.de>2014-05-26 08:24:03 -0400
commitbde8a8f23bbe6db51fa4e81644273af18fef3d7a (patch)
tree92ea0fbb1023bda284156ac561640f4502132409 /sound/firewire/fireworks/fireworks.c
parentb5b04336015e76eb52ffc188e16c9cee01821c7c (diff)
ALSA: fireworks: Add transaction and some commands
Fireworks uses own command and response. This commit adds functionality to transact and adds some commands required for sound card instance and kernel streaming. There are two ways to deliver substance of this transaction: 1.AV/C vendor dependent command for command/response 2.Async transaction to specific addresses for command/response By way 1, I confirm AudioFire12 cannot correctly response to some commands with firmware version 5.0 or later. This is also confirmed by FFADO. So this driver implement way 2. The address for response gives an issue. When this driver allocate own callback function into the address, then no one can allocate its own callback function. This situation is not good for applications in user-land. This issue is solved in later commit. I note there is a command to change the address for response if the device supports. But this driver uses default value. So users should not execute this command as long as hoping this driver works correctly. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/fireworks/fireworks.c')
-rw-r--r--sound/firewire/fireworks/fireworks.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index ad719a1d5353..6fa3a5d725d5 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -59,6 +59,50 @@ static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
59/* unknown as product */ 59/* unknown as product */
60#define MODEL_GIBSON_GOLDTOP 0x00afb9 60#define MODEL_GIBSON_GOLDTOP 0x00afb9
61 61
62/* part of hardware capability flags */
63#define FLAG_RESP_ADDR_CHANGABLE 0
64
65static int
66get_hardware_info(struct snd_efw *efw)
67{
68 struct fw_device *fw_dev = fw_parent_device(efw->unit);
69 struct snd_efw_hwinfo *hwinfo;
70 char version[12] = {0};
71 int err;
72
73 hwinfo = kzalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL);
74 if (hwinfo == NULL)
75 return -ENOMEM;
76
77 err = snd_efw_command_get_hwinfo(efw, hwinfo);
78 if (err < 0)
79 goto end;
80
81 /* firmware version for communication chipset */
82 snprintf(version, sizeof(version), "%u.%u",
83 (hwinfo->arm_version >> 24) & 0xff,
84 (hwinfo->arm_version >> 16) & 0xff);
85 if (err < 0)
86 goto end;
87
88 strcpy(efw->card->driver, "Fireworks");
89 strcpy(efw->card->shortname, hwinfo->model_name);
90 strcpy(efw->card->mixername, hwinfo->model_name);
91 snprintf(efw->card->longname, sizeof(efw->card->longname),
92 "%s %s v%s, GUID %08x%08x at %s, S%d",
93 hwinfo->vendor_name, hwinfo->model_name, version,
94 hwinfo->guid_hi, hwinfo->guid_lo,
95 dev_name(&efw->unit->device), 100 << fw_dev->max_speed);
96 if (err < 0)
97 goto end;
98
99 if (hwinfo->flags & BIT(FLAG_RESP_ADDR_CHANGABLE))
100 efw->resp_addr_changable = true;
101end:
102 kfree(hwinfo);
103 return err;
104}
105
62static void 106static void
63efw_card_free(struct snd_card *card) 107efw_card_free(struct snd_card *card)
64{ 108{
@@ -107,14 +151,14 @@ efw_probe(struct fw_unit *unit,
107 mutex_init(&efw->mutex); 151 mutex_init(&efw->mutex);
108 spin_lock_init(&efw->lock); 152 spin_lock_init(&efw->lock);
109 153
110 strcpy(efw->card->driver, "Fireworks"); 154 err = get_hardware_info(efw);
111 strcpy(efw->card->shortname, efw->card->driver); 155 if (err < 0)
112 strcpy(efw->card->longname, efw->card->driver); 156 goto error;
113 strcpy(efw->card->mixername, efw->card->driver);
114 157
115 err = snd_card_register(card); 158 err = snd_card_register(card);
116 if (err < 0) 159 if (err < 0)
117 goto error; 160 goto error;
161
118 dev_set_drvdata(&unit->device, efw); 162 dev_set_drvdata(&unit->device, efw);
119end: 163end:
120 mutex_unlock(&devices_mutex); 164 mutex_unlock(&devices_mutex);
@@ -127,7 +171,8 @@ error:
127 171
128static void efw_update(struct fw_unit *unit) 172static void efw_update(struct fw_unit *unit)
129{ 173{
130 return; 174 struct snd_efw *efw = dev_get_drvdata(&unit->device);
175 snd_efw_transaction_bus_reset(efw->unit);
131} 176}
132 177
133static void efw_remove(struct fw_unit *unit) 178static void efw_remove(struct fw_unit *unit)
@@ -169,11 +214,23 @@ static struct fw_driver efw_driver = {
169 214
170static int __init snd_efw_init(void) 215static int __init snd_efw_init(void)
171{ 216{
172 return driver_register(&efw_driver.driver); 217 int err;
218
219 err = snd_efw_transaction_register();
220 if (err < 0)
221 goto end;
222
223 err = driver_register(&efw_driver.driver);
224 if (err < 0)
225 snd_efw_transaction_unregister();
226
227end:
228 return err;
173} 229}
174 230
175static void __exit snd_efw_exit(void) 231static void __exit snd_efw_exit(void)
176{ 232{
233 snd_efw_transaction_unregister();
177 driver_unregister(&efw_driver.driver); 234 driver_unregister(&efw_driver.driver);
178 mutex_destroy(&devices_mutex); 235 mutex_destroy(&devices_mutex);
179} 236}