dice.c 9.0 KB
Newer Older
C
Clemens Ladisch 已提交
1 2 3 4 5 6 7
/*
 * TC Applied Technologies Digital Interface Communications Engine driver
 *
 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
 * Licensed under the terms of the GNU General Public License, version 2.
 */

8
#include "dice.h"
C
Clemens Ladisch 已提交
9 10 11 12 13

MODULE_DESCRIPTION("DICE driver");
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_LICENSE("GPL v2");

14
#define OUI_WEISS		0x001c6a
15
#define OUI_LOUD		0x000ff2
16 17 18

#define DICE_CATEGORY_ID	0x04
#define WEISS_CATEGORY_ID	0x00
19
#define LOUD_CATEGORY_ID	0x10
20

21 22
#define PROBE_DELAY_MS		(2 * MSEC_PER_SEC)

23
static int check_dice_category(struct fw_unit *unit)
24 25 26
{
	struct fw_device *device = fw_parent_device(unit);
	struct fw_csr_iterator it;
27 28
	int key, val, vendor = -1, model = -1;
	unsigned int category;
29

30 31 32
	/*
	 * Check that GUID and unit directory are constructed according to DICE
	 * rules, i.e., that the specifier ID is the GUID's OUI, and that the
33 34
	 * GUID chip ID consists of the 8-bit category ID, the 10-bit product
	 * ID, and a 22-bit serial number.
35 36
	 */
	fw_csr_iterator_init(&it, unit->directory);
37
	while (fw_csr_iterator_next(&it, &key, &val)) {
38 39
		switch (key) {
		case CSR_SPECIFIER_ID:
40
			vendor = val;
41 42
			break;
		case CSR_MODEL:
43
			model = val;
44 45 46
			break;
		}
	}
47 48
	if (vendor == OUI_WEISS)
		category = WEISS_CATEGORY_ID;
49 50
	else if (vendor == OUI_LOUD)
		category = LOUD_CATEGORY_ID;
51 52 53
	else
		category = DICE_CATEGORY_ID;
	if (device->config_rom[3] != ((vendor << 8) | category) ||
54 55
	    device->config_rom[4] >> 22 != model)
		return -ENODEV;
56

57
	return 0;
58 59
}

60 61
static int highest_supported_mode_rate(struct snd_dice *dice,
				       unsigned int mode, unsigned int *rate)
62
{
63
	unsigned int i, m;
64

65 66 67 68 69 70 71 72 73
	for (i = ARRAY_SIZE(snd_dice_rates); i > 0; i--) {
		*rate = snd_dice_rates[i - 1];
		if (snd_dice_stream_get_rate_mode(dice, *rate, &m) < 0)
			continue;
		if (mode == m)
			break;
	}
	if (i == 0)
		return -EINVAL;
74

75
	return 0;
76 77
}

78
static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode)
79 80
{
	__be32 values[2];
81 82
	unsigned int rate;
	int err;
83

84
	if (highest_supported_mode_rate(dice, mode, &rate) < 0) {
85 86
		dice->tx_channels[mode] = 0;
		dice->tx_midi_ports[mode] = 0;
87 88 89 90 91
		dice->rx_channels[mode] = 0;
		dice->rx_midi_ports[mode] = 0;
		return 0;
	}

92
	err = snd_dice_transaction_set_rate(dice, rate);
93 94 95
	if (err < 0)
		return err;

96 97 98 99 100 101 102 103
	err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
					   values, sizeof(values));
	if (err < 0)
		return err;

	dice->tx_channels[mode]   = be32_to_cpu(values[0]);
	dice->tx_midi_ports[mode] = be32_to_cpu(values[1]);

104 105
	err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
					   values, sizeof(values));
106 107 108 109 110 111 112 113 114
	if (err < 0)
		return err;

	dice->rx_channels[mode]   = be32_to_cpu(values[0]);
	dice->rx_midi_ports[mode] = be32_to_cpu(values[1]);

	return 0;
}

115
static int dice_read_params(struct snd_dice *dice)
C
Clemens Ladisch 已提交
116
{
117
	__be32 value;
118
	int mode, err;
C
Clemens Ladisch 已提交
119

120
	/* some very old firmwares don't tell about their clock support */
121 122 123 124
	if (dice->clock_caps > 0) {
		err = snd_dice_transaction_read_global(dice,
						GLOBAL_CLOCK_CAPABILITIES,
						&value, 4);
125 126 127 128 129 130 131 132 133 134 135
		if (err < 0)
			return err;
		dice->clock_caps = be32_to_cpu(value);
	} else {
		/* this should be supported by any device */
		dice->clock_caps = CLOCK_CAP_RATE_44100 |
				   CLOCK_CAP_RATE_48000 |
				   CLOCK_CAP_SOURCE_ARX1 |
				   CLOCK_CAP_SOURCE_INTERNAL;
	}

136 137 138 139 140 141
	for (mode = 2; mode >= 0; --mode) {
		err = dice_read_mode_params(dice, mode);
		if (err < 0)
			return err;
	}

C
Clemens Ladisch 已提交
142 143 144
	return 0;
}

145
static void dice_card_strings(struct snd_dice *dice)
C
Clemens Ladisch 已提交
146 147 148 149 150 151 152 153 154 155 156
{
	struct snd_card *card = dice->card;
	struct fw_device *dev = fw_parent_device(dice->unit);
	char vendor[32], model[32];
	unsigned int i;
	int err;

	strcpy(card->driver, "DICE");

	strcpy(card->shortname, "DICE");
	BUILD_BUG_ON(NICK_NAME_SIZE < sizeof(card->shortname));
157 158 159
	err = snd_dice_transaction_read_global(dice, GLOBAL_NICK_NAME,
					       card->shortname,
					       sizeof(card->shortname));
C
Clemens Ladisch 已提交
160 161 162 163 164 165 166 167 168 169 170 171 172
	if (err >= 0) {
		/* DICE strings are returned in "always-wrong" endianness */
		BUILD_BUG_ON(sizeof(card->shortname) % 4 != 0);
		for (i = 0; i < sizeof(card->shortname); i += 4)
			swab32s((u32 *)&card->shortname[i]);
		card->shortname[sizeof(card->shortname) - 1] = '\0';
	}

	strcpy(vendor, "?");
	fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor));
	strcpy(model, "?");
	fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model));
	snprintf(card->longname, sizeof(card->longname),
173 174
		 "%s %s (serial %u) at %s, S%d",
		 vendor, model, dev->config_rom[4] & 0x3fffff,
C
Clemens Ladisch 已提交
175 176 177 178 179
		 dev_name(&dice->unit->device), 100 << dev->max_speed);

	strcpy(card->mixername, "DICE");
}

180 181 182 183 184 185 186 187 188 189
static void dice_free(struct snd_dice *dice)
{
	snd_dice_stream_destroy_duplex(dice);
	snd_dice_transaction_destroy(dice);
	fw_unit_put(dice->unit);

	mutex_destroy(&dice->mutex);
	kfree(dice);
}

190 191 192 193 194 195
/*
 * This module releases the FireWire unit data after all ALSA character devices
 * are released by applications. This is for releasing stream data or finishing
 * transactions safely. Thus at returning from .remove(), this module still keep
 * references for the unit.
 */
196 197
static void dice_card_free(struct snd_card *card)
{
198
	dice_free(card->private_data);
199 200
}

201
static void do_registration(struct work_struct *work)
C
Clemens Ladisch 已提交
202
{
203
	struct snd_dice *dice = container_of(work, struct snd_dice, dwork.work);
C
Clemens Ladisch 已提交
204 205
	int err;

206 207
	if (dice->registered)
		return;
208

209 210
	err = snd_card_new(&dice->unit->device, -1, NULL, THIS_MODULE, 0,
			   &dice->card);
C
Clemens Ladisch 已提交
211
	if (err < 0)
212
		return;
C
Clemens Ladisch 已提交
213

214
	err = snd_dice_transaction_init(dice);
C
Clemens Ladisch 已提交
215
	if (err < 0)
216
		goto error;
217 218 219

	err = dice_read_params(dice);
	if (err < 0)
220
		goto error;
C
Clemens Ladisch 已提交
221 222 223

	dice_card_strings(dice);

224 225
	snd_dice_create_proc(dice);

226
	err = snd_dice_create_pcm(dice);
C
Clemens Ladisch 已提交
227 228 229
	if (err < 0)
		goto error;

230
	err = snd_dice_create_midi(dice);
C
Clemens Ladisch 已提交
231 232 233
	if (err < 0)
		goto error;

234
	err = snd_dice_create_hwdep(dice);
235 236 237
	if (err < 0)
		goto error;

238
	err = snd_card_register(dice->card);
C
Clemens Ladisch 已提交
239 240 241
	if (err < 0)
		goto error;

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
	/*
	 * After registered, dice instance can be released corresponding to
	 * releasing the sound card instance.
	 */
	dice->card->private_free = dice_card_free;
	dice->card->private_data = dice;
	dice->registered = true;

	return;
error:
	snd_dice_transaction_destroy(dice);
	snd_card_free(dice->card);
	dev_info(&dice->unit->device,
		 "Sound card registration failed: %d\n", err);
}

static void schedule_registration(struct snd_dice *dice)
{
	struct fw_card *fw_card = fw_parent_device(dice->unit)->card;
	u64 now, delay;

	now = get_jiffies_64();
	delay = fw_card->reset_jiffies + msecs_to_jiffies(PROBE_DELAY_MS);

	if (time_after64(delay, now))
		delay -= now;
	else
		delay = 0;

	mod_delayed_work(system_wq, &dice->dwork, delay);
}

static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
{
	struct snd_dice *dice;
	int err;

	err = check_dice_category(unit);
	if (err < 0)
		return -ENODEV;

	/* Allocate this independent of sound card instance. */
	dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL);
	if (dice == NULL)
		return -ENOMEM;

	dice->unit = fw_unit_get(unit);
	dev_set_drvdata(&unit->device, dice);

	spin_lock_init(&dice->lock);
	mutex_init(&dice->mutex);
	init_completion(&dice->clock_accepted);
	init_waitqueue_head(&dice->hwdep_wait);

	err = snd_dice_stream_init_duplex(dice);
297
	if (err < 0) {
298 299
		dice_free(dice);
		return err;
300
	}
C
Clemens Ladisch 已提交
301

302 303 304 305 306
	/* Allocate and register this sound card later. */
	INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
	schedule_registration(dice);

	return 0;
C
Clemens Ladisch 已提交
307 308 309 310
}

static void dice_remove(struct fw_unit *unit)
{
311
	struct snd_dice *dice = dev_get_drvdata(&unit->device);
C
Clemens Ladisch 已提交
312

313 314 315 316 317 318 319 320 321 322 323 324 325 326
	/*
	 * Confirm to stop the work for registration before the sound card is
	 * going to be released. The work is not scheduled again because bus
	 * reset handler is not called anymore.
	 */
	cancel_delayed_work_sync(&dice->dwork);

	if (dice->registered) {
		/* No need to wait for releasing card object in this context. */
		snd_card_free_when_closed(dice->card);
	} else {
		/* Don't forget this case. */
		dice_free(dice);
	}
C
Clemens Ladisch 已提交
327 328 329 330
}

static void dice_bus_reset(struct fw_unit *unit)
{
331
	struct snd_dice *dice = dev_get_drvdata(&unit->device);
C
Clemens Ladisch 已提交
332

333 334 335 336
	/* Postpone a workqueue for deferred registration. */
	if (!dice->registered)
		schedule_registration(dice);

337 338 339
	/* The handler address register becomes initialized. */
	snd_dice_transaction_reinit(dice);

340 341 342 343 344 345 346 347 348
	/*
	 * After registration, userspace can start packet streaming, then this
	 * code block works fine.
	 */
	if (dice->registered) {
		mutex_lock(&dice->mutex);
		snd_dice_stream_update_duplex(dice);
		mutex_unlock(&dice->mutex);
	}
C
Clemens Ladisch 已提交
349 350 351 352 353 354
}

#define DICE_INTERFACE	0x000001

static const struct ieee1394_device_id dice_id_table[] = {
	{
355 356
		.match_flags = IEEE1394_MATCH_VERSION,
		.version     = DICE_INTERFACE,
C
Clemens Ladisch 已提交
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
	},
	{ }
};
MODULE_DEVICE_TABLE(ieee1394, dice_id_table);

static struct fw_driver dice_driver = {
	.driver   = {
		.owner	= THIS_MODULE,
		.name	= KBUILD_MODNAME,
		.bus	= &fw_bus_type,
	},
	.probe    = dice_probe,
	.update   = dice_bus_reset,
	.remove   = dice_remove,
	.id_table = dice_id_table,
};

static int __init alsa_dice_init(void)
{
	return driver_register(&dice_driver.driver);
}

static void __exit alsa_dice_exit(void)
{
	driver_unregister(&dice_driver.driver);
}

module_init(alsa_dice_init);
module_exit(alsa_dice_exit);