dice.c 8.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 23 24 25 26 27 28 29 30 31

static int dice_interface_check(struct fw_unit *unit)
{
	static const int min_values[10] = {
		10, 0x64 / 4,
		10, 0x18 / 4,
		10, 0x18 / 4,
		0, 0,
		0, 0,
	};
	struct fw_device *device = fw_parent_device(unit);
	struct fw_csr_iterator it;
32
	int key, val, vendor = -1, model = -1, err;
33
	unsigned int category, i;
34 35
	__be32 *pointers;
	u32 value;
36 37
	__be32 version;

38 39 40 41 42
	pointers = kmalloc_array(ARRAY_SIZE(min_values), sizeof(__be32),
				 GFP_KERNEL);
	if (pointers == NULL)
		return -ENOMEM;

43 44 45
	/*
	 * 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
46 47
	 * GUID chip ID consists of the 8-bit category ID, the 10-bit product
	 * ID, and a 22-bit serial number.
48 49
	 */
	fw_csr_iterator_init(&it, unit->directory);
50
	while (fw_csr_iterator_next(&it, &key, &val)) {
51 52
		switch (key) {
		case CSR_SPECIFIER_ID:
53
			vendor = val;
54 55
			break;
		case CSR_MODEL:
56
			model = val;
57 58 59
			break;
		}
	}
60 61
	if (vendor == OUI_WEISS)
		category = WEISS_CATEGORY_ID;
62 63
	else if (vendor == OUI_LOUD)
		category = LOUD_CATEGORY_ID;
64 65 66
	else
		category = DICE_CATEGORY_ID;
	if (device->config_rom[3] != ((vendor << 8) | category) ||
67 68 69 70
	    device->config_rom[4] >> 22 != model) {
		err = -ENODEV;
		goto end;
	}
71 72 73 74 75 76 77

	/*
	 * Check that the sub address spaces exist and are located inside the
	 * private address space.  The minimum values are chosen so that all
	 * minimally required registers are included.
	 */
	err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST,
78 79 80 81 82 83 84
				 DICE_PRIVATE_SPACE, pointers,
				 sizeof(__be32) * ARRAY_SIZE(min_values), 0);
	if (err < 0) {
		err = -ENODEV;
		goto end;
	}
	for (i = 0; i < ARRAY_SIZE(min_values); ++i) {
85
		value = be32_to_cpu(pointers[i]);
86 87 88 89
		if (value < min_values[i] || value >= 0x40000) {
			err = -ENODEV;
			goto end;
		}
90 91 92 93 94 95 96 97 98
	}

	/*
	 * Check that the implemented DICE driver specification major version
	 * number matches.
	 */
	err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
				 DICE_PRIVATE_SPACE +
				 be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
99
				 &version, 4, 0);
100 101 102 103
	if (err < 0) {
		err = -ENODEV;
		goto end;
	}
104 105 106
	if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) {
		dev_err(&unit->device,
			"unknown DICE version: 0x%08x\n", be32_to_cpu(version));
107 108
		err = -ENODEV;
		goto end;
109
	}
110 111
end:
	return err;
112 113
}

114 115
static int highest_supported_mode_rate(struct snd_dice *dice,
				       unsigned int mode, unsigned int *rate)
116
{
117
	unsigned int i, m;
118

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

129
	return 0;
130 131
}

132
static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode)
133 134
{
	__be32 values[2];
135 136
	unsigned int rate;
	int err;
137

138
	if (highest_supported_mode_rate(dice, mode, &rate) < 0) {
139 140
		dice->tx_channels[mode] = 0;
		dice->tx_midi_ports[mode] = 0;
141 142 143 144 145
		dice->rx_channels[mode] = 0;
		dice->rx_midi_ports[mode] = 0;
		return 0;
	}

146
	err = snd_dice_transaction_set_rate(dice, rate);
147 148 149
	if (err < 0)
		return err;

150 151 152 153 154 155 156 157
	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]);

158 159
	err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
					   values, sizeof(values));
160 161 162 163 164 165 166 167 168
	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;
}

169
static int dice_read_params(struct snd_dice *dice)
C
Clemens Ladisch 已提交
170
{
171
	__be32 value;
172
	int mode, err;
C
Clemens Ladisch 已提交
173

174
	/* some very old firmwares don't tell about their clock support */
175 176 177 178
	if (dice->clock_caps > 0) {
		err = snd_dice_transaction_read_global(dice,
						GLOBAL_CLOCK_CAPABILITIES,
						&value, 4);
179 180 181 182 183 184 185 186 187 188 189
		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;
	}

190 191 192 193 194 195
	for (mode = 2; mode >= 0; --mode) {
		err = dice_read_mode_params(dice, mode);
		if (err < 0)
			return err;
	}

C
Clemens Ladisch 已提交
196 197 198
	return 0;
}

199
static void dice_card_strings(struct snd_dice *dice)
C
Clemens Ladisch 已提交
200 201 202 203 204 205 206 207 208 209 210
{
	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));
211 212 213
	err = snd_dice_transaction_read_global(dice, GLOBAL_NICK_NAME,
					       card->shortname,
					       sizeof(card->shortname));
C
Clemens Ladisch 已提交
214 215 216 217 218 219 220 221 222 223 224 225 226
	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),
227 228
		 "%s %s (serial %u) at %s, S%d",
		 vendor, model, dev->config_rom[4] & 0x3fffff,
C
Clemens Ladisch 已提交
229 230 231 232 233
		 dev_name(&dice->unit->device), 100 << dev->max_speed);

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

234 235 236 237 238 239
/*
 * 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.
 */
240 241 242 243
static void dice_card_free(struct snd_card *card)
{
	struct snd_dice *dice = card->private_data;

244
	snd_dice_stream_destroy_duplex(dice);
245
	snd_dice_transaction_destroy(dice);
246 247
	fw_unit_put(dice->unit);

248 249 250
	mutex_destroy(&dice->mutex);
}

C
Clemens Ladisch 已提交
251 252 253
static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
{
	struct snd_card *card;
254
	struct snd_dice *dice;
C
Clemens Ladisch 已提交
255 256
	int err;

257 258
	err = dice_interface_check(unit);
	if (err < 0)
259
		goto end;
260

261 262
	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
			   sizeof(*dice), &card);
C
Clemens Ladisch 已提交
263
	if (err < 0)
264
		goto end;
C
Clemens Ladisch 已提交
265 266 267

	dice = card->private_data;
	dice->card = card;
268
	dice->unit = fw_unit_get(unit);
269 270
	card->private_free = dice_card_free;

271
	spin_lock_init(&dice->lock);
C
Clemens Ladisch 已提交
272
	mutex_init(&dice->mutex);
273
	init_completion(&dice->clock_accepted);
274
	init_waitqueue_head(&dice->hwdep_wait);
C
Clemens Ladisch 已提交
275

276
	err = snd_dice_transaction_init(dice);
C
Clemens Ladisch 已提交
277
	if (err < 0)
278
		goto error;
279 280 281

	err = dice_read_params(dice);
	if (err < 0)
282
		goto error;
C
Clemens Ladisch 已提交
283 284 285

	dice_card_strings(dice);

286
	err = snd_dice_create_pcm(dice);
C
Clemens Ladisch 已提交
287 288 289
	if (err < 0)
		goto error;

290
	err = snd_dice_create_hwdep(dice);
C
Clemens Ladisch 已提交
291 292 293
	if (err < 0)
		goto error;

294
	snd_dice_create_proc(dice);
295

296 297 298 299
	err = snd_dice_create_midi(dice);
	if (err < 0)
		goto error;

300
	err = snd_dice_stream_init_duplex(dice);
C
Clemens Ladisch 已提交
301 302 303
	if (err < 0)
		goto error;

304 305
	err = snd_card_register(card);
	if (err < 0) {
306
		snd_dice_stream_destroy_duplex(dice);
307 308
		goto error;
	}
C
Clemens Ladisch 已提交
309

310 311 312
	dev_set_drvdata(&unit->device, dice);
end:
	return err;
C
Clemens Ladisch 已提交
313 314 315 316 317 318 319
error:
	snd_card_free(card);
	return err;
}

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

322
	/* No need to wait for releasing card object in this context. */
C
Clemens Ladisch 已提交
323 324 325 326 327
	snd_card_free_when_closed(dice->card);
}

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

330 331 332
	/* The handler address register becomes initialized. */
	snd_dice_transaction_reinit(dice);

S
Stefan Richter 已提交
333
	mutex_lock(&dice->mutex);
334
	snd_dice_stream_update_duplex(dice);
C
Clemens Ladisch 已提交
335 336 337 338 339 340 341
	mutex_unlock(&dice->mutex);
}

#define DICE_INTERFACE	0x000001

static const struct ieee1394_device_id dice_id_table[] = {
	{
342 343
		.match_flags = IEEE1394_MATCH_VERSION,
		.version     = DICE_INTERFACE,
C
Clemens Ladisch 已提交
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
	},
	{ }
};
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);