aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/tascam
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2015-10-12 06:10:25 -0400
committerTakashi Iwai <tiwai@suse.de>2015-10-12 08:17:02 -0400
commit53b3ffee788559fe26d32f21b223bf4bad959477 (patch)
treefaf59f481b5a142d282bda00a3f2d4839e23ea8e /sound/firewire/tascam
parente65e2cb99e44704f63b76e4395092b0533bef88b (diff)
ALSA: firewire-tascam: change device probing processing
Currently, this driver picks up model name with be32_to_cpu() macro to align characters. This is wrong operation because the result is different depending on CPU endiannness. Additionally, vendor released several versions of firmware for this series. It's not better to assign model-dependent information to device entry according to the version field. This commit fixes these bugs. The name of model is picked up correctly and used to identify model-dependent information. Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> Fixes: c0949b278515 ('ALSA: firewire-tascam: add skeleton for TASCAM FireWire series') Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/tascam')
-rw-r--r--sound/firewire/tascam/tascam.c78
1 files changed, 32 insertions, 46 deletions
diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c
index dc07e3edbf5a..c6747a45795b 100644
--- a/sound/firewire/tascam/tascam.c
+++ b/sound/firewire/tascam/tascam.c
@@ -24,16 +24,6 @@ static struct snd_tscm_spec model_specs[] = {
24 .is_controller = true, 24 .is_controller = true,
25 }, 25 },
26 { 26 {
27 .name = "FW-1804",
28 .has_adat = true,
29 .has_spdif = true,
30 .pcm_capture_analog_channels = 8,
31 .pcm_playback_analog_channels = 2,
32 .midi_capture_ports = 2,
33 .midi_playback_ports = 4,
34 .is_controller = false,
35 },
36 {
37 .name = "FW-1082", 27 .name = "FW-1082",
38 .has_adat = false, 28 .has_adat = false,
39 .has_spdif = true, 29 .has_spdif = true,
@@ -43,34 +33,46 @@ static struct snd_tscm_spec model_specs[] = {
43 .midi_playback_ports = 2, 33 .midi_playback_ports = 2,
44 .is_controller = true, 34 .is_controller = true,
45 }, 35 },
36 /* FW-1804 may be supported. */
46}; 37};
47 38
48static int check_name(struct snd_tscm *tscm) 39static int identify_model(struct snd_tscm *tscm)
49{ 40{
50 struct fw_device *fw_dev = fw_parent_device(tscm->unit); 41 struct fw_device *fw_dev = fw_parent_device(tscm->unit);
51 char vendor[8]; 42 const u32 *config_rom = fw_dev->config_rom;
52 char model[8]; 43 char model[8];
53 __u32 data; 44 unsigned int i;
54 45 u8 c;
55 /* Retrieve model name. */ 46
56 data = be32_to_cpu(fw_dev->config_rom[28]); 47 if (fw_dev->config_rom_length < 30) {
57 memcpy(model, &data, 4); 48 dev_err(&tscm->unit->device,
58 data = be32_to_cpu(fw_dev->config_rom[29]); 49 "Configuration ROM is too short.\n");
59 memcpy(model + 4, &data, 4); 50 return -ENODEV;
60 model[7] = '\0'; 51 }
61 52
62 /* Retrieve vendor name. */ 53 /* Pick up model name from certain addresses. */
63 data = be32_to_cpu(fw_dev->config_rom[23]); 54 for (i = 0; i < 8; i++) {
64 memcpy(vendor, &data, 4); 55 c = config_rom[28 + i / 4] >> (24 - 8 * (i % 4));
65 data = be32_to_cpu(fw_dev->config_rom[24]); 56 if (c == '\0')
66 memcpy(vendor + 4, &data, 4); 57 break;
67 vendor[7] = '\0'; 58 model[i] = c;
59 }
60 model[i] = '\0';
61
62 for (i = 0; i < ARRAY_SIZE(model_specs); i++) {
63 if (strcmp(model, model_specs[i].name) == 0) {
64 tscm->spec = &model_specs[i];
65 break;
66 }
67 }
68 if (tscm->spec == NULL)
69 return -ENODEV;
68 70
69 strcpy(tscm->card->driver, "FW-TASCAM"); 71 strcpy(tscm->card->driver, "FW-TASCAM");
70 strcpy(tscm->card->shortname, model); 72 strcpy(tscm->card->shortname, model);
71 strcpy(tscm->card->mixername, model); 73 strcpy(tscm->card->mixername, model);
72 snprintf(tscm->card->longname, sizeof(tscm->card->longname), 74 snprintf(tscm->card->longname, sizeof(tscm->card->longname),
73 "%s %s, GUID %08x%08x at %s, S%d", vendor, model, 75 "TASCAM %s, GUID %08x%08x at %s, S%d", model,
74 cpu_to_be32(fw_dev->config_rom[3]), 76 cpu_to_be32(fw_dev->config_rom[3]),
75 cpu_to_be32(fw_dev->config_rom[4]), 77 cpu_to_be32(fw_dev->config_rom[4]),
76 dev_name(&tscm->unit->device), 100 << fw_dev->max_speed); 78 dev_name(&tscm->unit->device), 100 << fw_dev->max_speed);
@@ -108,13 +110,12 @@ static int snd_tscm_probe(struct fw_unit *unit,
108 tscm = card->private_data; 110 tscm = card->private_data;
109 tscm->card = card; 111 tscm->card = card;
110 tscm->unit = fw_unit_get(unit); 112 tscm->unit = fw_unit_get(unit);
111 tscm->spec = (const struct snd_tscm_spec *)entry->driver_data;
112 113
113 mutex_init(&tscm->mutex); 114 mutex_init(&tscm->mutex);
114 spin_lock_init(&tscm->lock); 115 spin_lock_init(&tscm->lock);
115 init_waitqueue_head(&tscm->hwdep_wait); 116 init_waitqueue_head(&tscm->hwdep_wait);
116 117
117 err = check_name(tscm); 118 err = identify_model(tscm);
118 if (err < 0) 119 if (err < 0)
119 goto error; 120 goto error;
120 121
@@ -172,27 +173,12 @@ static void snd_tscm_remove(struct fw_unit *unit)
172} 173}
173 174
174static const struct ieee1394_device_id snd_tscm_id_table[] = { 175static const struct ieee1394_device_id snd_tscm_id_table[] = {
175 /* FW-1082 */
176 {
177 .match_flags = IEEE1394_MATCH_VENDOR_ID |
178 IEEE1394_MATCH_SPECIFIER_ID |
179 IEEE1394_MATCH_VERSION,
180 .vendor_id = 0x00022e,
181 .specifier_id = 0x00022e,
182 .version = 0x800003,
183 .driver_data = (kernel_ulong_t)&model_specs[2],
184 },
185 /* FW-1884 */
186 { 176 {
187 .match_flags = IEEE1394_MATCH_VENDOR_ID | 177 .match_flags = IEEE1394_MATCH_VENDOR_ID |
188 IEEE1394_MATCH_SPECIFIER_ID | 178 IEEE1394_MATCH_SPECIFIER_ID,
189 IEEE1394_MATCH_VERSION,
190 .vendor_id = 0x00022e, 179 .vendor_id = 0x00022e,
191 .specifier_id = 0x00022e, 180 .specifier_id = 0x00022e,
192 .version = 0x800000,
193 .driver_data = (kernel_ulong_t)&model_specs[0],
194 }, 181 },
195 /* FW-1804 mey be supported if IDs are clear. */
196 /* FE-08 requires reverse-engineering because it just has faders. */ 182 /* FE-08 requires reverse-engineering because it just has faders. */
197 {} 183 {}
198}; 184};