dice.c 7.7 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
static int check_clock_caps(struct snd_dice *dice)
C
Clemens Ladisch 已提交
61
{
62
	__be32 value;
63
	int err;
C
Clemens Ladisch 已提交
64

65
	/* some very old firmwares don't tell about their clock support */
66 67 68 69
	if (dice->clock_caps > 0) {
		err = snd_dice_transaction_read_global(dice,
						GLOBAL_CLOCK_CAPABILITIES,
						&value, 4);
70 71 72 73 74 75 76 77 78 79 80
		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;
	}

C
Clemens Ladisch 已提交
81 82 83
	return 0;
}

84
static void dice_card_strings(struct snd_dice *dice)
C
Clemens Ladisch 已提交
85 86 87 88 89 90 91 92 93 94 95
{
	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));
96 97 98
	err = snd_dice_transaction_read_global(dice, GLOBAL_NICK_NAME,
					       card->shortname,
					       sizeof(card->shortname));
C
Clemens Ladisch 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111
	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),
112 113
		 "%s %s (serial %u) at %s, S%d",
		 vendor, model, dev->config_rom[4] & 0x3fffff,
C
Clemens Ladisch 已提交
114 115 116 117 118
		 dev_name(&dice->unit->device), 100 << dev->max_speed);

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

119 120 121 122 123 124 125 126 127 128
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);
}

129 130 131 132 133 134
/*
 * 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.
 */
135 136
static void dice_card_free(struct snd_card *card)
{
137
	dice_free(card->private_data);
138 139
}

140
static void do_registration(struct work_struct *work)
C
Clemens Ladisch 已提交
141
{
142
	struct snd_dice *dice = container_of(work, struct snd_dice, dwork.work);
C
Clemens Ladisch 已提交
143 144
	int err;

145 146
	if (dice->registered)
		return;
147

148 149
	err = snd_card_new(&dice->unit->device, -1, NULL, THIS_MODULE, 0,
			   &dice->card);
C
Clemens Ladisch 已提交
150
	if (err < 0)
151
		return;
C
Clemens Ladisch 已提交
152

153
	err = snd_dice_transaction_init(dice);
C
Clemens Ladisch 已提交
154
	if (err < 0)
155
		goto error;
156

157
	err = check_clock_caps(dice);
158
	if (err < 0)
159
		goto error;
C
Clemens Ladisch 已提交
160 161 162

	dice_card_strings(dice);

163 164
	snd_dice_create_proc(dice);

165
	err = snd_dice_create_pcm(dice);
C
Clemens Ladisch 已提交
166 167 168
	if (err < 0)
		goto error;

169
	err = snd_dice_create_midi(dice);
C
Clemens Ladisch 已提交
170 171 172
	if (err < 0)
		goto error;

173
	err = snd_dice_create_hwdep(dice);
174 175 176
	if (err < 0)
		goto error;

177
	err = snd_card_register(dice->card);
C
Clemens Ladisch 已提交
178 179 180
	if (err < 0)
		goto error;

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
	/*
	 * 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);
236
	if (err < 0) {
237 238
		dice_free(dice);
		return err;
239
	}
C
Clemens Ladisch 已提交
240

241 242 243 244 245
	/* Allocate and register this sound card later. */
	INIT_DEFERRABLE_WORK(&dice->dwork, do_registration);
	schedule_registration(dice);

	return 0;
C
Clemens Ladisch 已提交
246 247 248 249
}

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

252 253 254 255 256 257 258 259 260 261 262 263 264 265
	/*
	 * 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 已提交
266 267 268 269
}

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

272 273 274 275
	/* Postpone a workqueue for deferred registration. */
	if (!dice->registered)
		schedule_registration(dice);

276 277 278
	/* The handler address register becomes initialized. */
	snd_dice_transaction_reinit(dice);

279 280 281 282 283 284 285 286 287
	/*
	 * 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 已提交
288 289 290 291 292 293
}

#define DICE_INTERFACE	0x000001

static const struct ieee1394_device_id dice_id_table[] = {
	{
294 295
		.match_flags = IEEE1394_MATCH_VERSION,
		.version     = DICE_INTERFACE,
C
Clemens Ladisch 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
	},
	{ }
};
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);