示例#1
0
文件: bebob.c 项目: 19Dan01/linux
static int
bebob_probe(struct fw_unit *unit,
	    const struct ieee1394_device_id *entry)
{
	struct snd_card *card;
	struct snd_bebob *bebob;
	const struct snd_bebob_spec *spec;
	unsigned int card_index;
	int err;

	mutex_lock(&devices_mutex);

	for (card_index = 0; card_index < SNDRV_CARDS; card_index++) {
		if (!test_bit(card_index, devices_used) && enable[card_index])
			break;
	}
	if (card_index >= SNDRV_CARDS) {
		err = -ENOENT;
		goto end;
	}

	if ((entry->vendor_id == VEN_FOCUSRITE) &&
	    (entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH))
		spec = get_saffire_spec(unit);
	else if ((entry->vendor_id == VEN_MAUDIO1) &&
		 (entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH) &&
		 !check_audiophile_booted(unit))
		spec = NULL;
	else
		spec = (const struct snd_bebob_spec *)entry->driver_data;

	if (spec == NULL) {
		if ((entry->vendor_id == VEN_MAUDIO1) ||
		    (entry->vendor_id == VEN_MAUDIO2))
			err = snd_bebob_maudio_load_firmware(unit);
		else
			err = -ENOSYS;
		goto end;
	}

	err = snd_card_new(&unit->device, index[card_index], id[card_index],
			   THIS_MODULE, sizeof(struct snd_bebob), &card);
	if (err < 0)
		goto end;
	bebob = card->private_data;
	bebob->card_index = card_index;
	set_bit(card_index, devices_used);
	card->private_free = bebob_card_free;

	bebob->card = card;
	bebob->unit = fw_unit_get(unit);
	bebob->spec = spec;
	mutex_init(&bebob->mutex);
	spin_lock_init(&bebob->lock);
	init_waitqueue_head(&bebob->hwdep_wait);

	err = name_device(bebob, entry->vendor_id);
	if (err < 0)
		goto error;

	if ((entry->vendor_id == VEN_MAUDIO1) &&
	    (entry->model_id == MODEL_MAUDIO_FW1814))
		err = snd_bebob_maudio_special_discover(bebob, true);
	else if ((entry->vendor_id == VEN_MAUDIO1) &&
		 (entry->model_id == MODEL_MAUDIO_PROJECTMIX))
		err = snd_bebob_maudio_special_discover(bebob, false);
	else
		err = snd_bebob_stream_discover(bebob);
	if (err < 0)
		goto error;

	snd_bebob_proc_init(bebob);

	if ((bebob->midi_input_ports > 0) ||
	    (bebob->midi_output_ports > 0)) {
		err = snd_bebob_create_midi_devices(bebob);
		if (err < 0)
			goto error;
	}

	err = snd_bebob_create_pcm_devices(bebob);
	if (err < 0)
		goto error;

	err = snd_bebob_create_hwdep_device(bebob);
	if (err < 0)
		goto error;

	err = snd_bebob_stream_init_duplex(bebob);
	if (err < 0)
		goto error;

	if (!bebob->maudio_special_quirk) {
		err = snd_card_register(card);
		if (err < 0) {
			snd_bebob_stream_destroy_duplex(bebob);
			goto error;
		}
	} else {
		/*
		 * This is a workaround. This bus reset seems to have an effect
		 * to make devices correctly handling transactions. Without
		 * this, the devices have gap_count mismatch. This causes much
		 * failure of transaction.
		 *
		 * Just after registration, user-land application receive
		 * signals from dbus and starts I/Os. To avoid I/Os till the
		 * future bus reset, registration is done in next update().
		 */
		bebob->deferred_registration = true;
		fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card,
				      false, true);
	}

	dev_set_drvdata(&unit->device, bebob);
end:
	mutex_unlock(&devices_mutex);
	return err;
error:
	mutex_unlock(&devices_mutex);
	snd_card_free(card);
	return err;
}
示例#2
0
文件: bebob.c 项目: 513855417/linux
static void
do_registration(struct work_struct *work)
{
	struct snd_bebob *bebob =
			container_of(work, struct snd_bebob, dwork.work);
	unsigned int card_index;
	int err;

	if (bebob->registered)
		return;

	mutex_lock(&devices_mutex);

	for (card_index = 0; card_index < SNDRV_CARDS; card_index++) {
		if (!test_bit(card_index, devices_used) && enable[card_index])
			break;
	}
	if (card_index >= SNDRV_CARDS) {
		mutex_unlock(&devices_mutex);
		return;
	}

	err = snd_card_new(&bebob->unit->device, index[card_index],
			   id[card_index], THIS_MODULE, 0, &bebob->card);
	if (err < 0) {
		mutex_unlock(&devices_mutex);
		return;
	}

	err = name_device(bebob);
	if (err < 0)
		goto error;

	if (bebob->spec == &maudio_special_spec) {
		if (bebob->entry->model_id == MODEL_MAUDIO_FW1814)
			err = snd_bebob_maudio_special_discover(bebob, true);
		else
			err = snd_bebob_maudio_special_discover(bebob, false);
	} else {
		err = snd_bebob_stream_discover(bebob);
	}
	if (err < 0)
		goto error;

	err = snd_bebob_stream_init_duplex(bebob);
	if (err < 0)
		goto error;

	snd_bebob_proc_init(bebob);

	if (bebob->midi_input_ports > 0 || bebob->midi_output_ports > 0) {
		err = snd_bebob_create_midi_devices(bebob);
		if (err < 0)
			goto error;
	}

	err = snd_bebob_create_pcm_devices(bebob);
	if (err < 0)
		goto error;

	err = snd_bebob_create_hwdep_device(bebob);
	if (err < 0)
		goto error;

	err = snd_card_register(bebob->card);
	if (err < 0)
		goto error;

	set_bit(card_index, devices_used);
	mutex_unlock(&devices_mutex);

	/*
	 * After registered, bebob instance can be released corresponding to
	 * releasing the sound card instance.
	 */
	bebob->card->private_free = bebob_card_free;
	bebob->card->private_data = bebob;
	bebob->registered = true;

	return;
error:
	mutex_unlock(&devices_mutex);
	snd_bebob_stream_destroy_duplex(bebob);
	snd_card_free(bebob->card);
	dev_info(&bebob->unit->device,
		 "Sound card registration failed: %d\n", err);
}
示例#3
0
static int
snd_bebob_probe(struct fw_unit *unit,
		const struct ieee1394_device_id *entry)
{
	struct snd_card *card;
	struct snd_bebob *bebob;
	int card_index, err;

	mutex_lock(&devices_mutex);

	/* check registered cards */
	for (card_index = 0; card_index < SNDRV_CARDS; card_index += 1) {
		if (!(devices_used & BIT(card_index)) && enable[card_index])
			break;
	}
	if (card_index >= SNDRV_CARDS) {
		err = -ENOENT;
		goto end;
	}

	/* create card */
	err = snd_card_create(index[card_index], id[card_index],
			THIS_MODULE, sizeof(struct snd_bebob), &card);
	if (err < 0)
		goto end;
	card->private_free = snd_bebob_card_free;

	/* initialize myself */
	bebob = card->private_data;
	bebob->card = card;
	bebob->device = fw_parent_device(unit);
	bebob->unit = unit;
	bebob->card_index = -1;
	mutex_init(&bebob->mutex);
	spin_lock_init(&bebob->lock);

	bebob->spec = (const struct snd_bebob_spec *)entry->driver_data;

	/* try to load firmware if necessary */
	if (!bebob->spec->load)
		goto loaded;
	/* MAudio Audiophile has the same id for both  */
	else if ((entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH) &&
	         check_audiophile_booted(bebob))
		goto loaded;
	else {
		bebob->spec->load(bebob);
		/* just do this */
		err = 0;
		snd_printk(KERN_INFO"loading firmware\n");
		goto error;
	}

loaded:
	if (!bebob->spec->discover)
		goto error;
	err = bebob->spec->discover(bebob);
	if (err < 0)
		goto error;

	/* name device with communication */
	err = name_device(bebob, entry->vendor_id);
	if (err < 0)
		goto error;

	/* create devices */
	err = snd_bebob_create_pcm_devices(bebob);
	if (err < 0)
		goto error;


	err = snd_bebob_create_control_devices(bebob);
	if (err < 0)
		goto error;

	snd_bebob_create_midi_devices(bebob);

	/* proc interfaces */
	snd_bebob_proc_init(bebob);

	/* register card and device */
	snd_card_set_dev(card, &unit->device);
	err = snd_card_register(card);
	if (err < 0) {
		snd_card_free(card);
		goto error;
	}
	dev_set_drvdata(&unit->device, bebob);
	devices_used |= BIT(card_index);
	bebob->card_index = card_index;

	/* proved */
	err = 0;
	goto end;

error:
	snd_card_free(card);

end:
	mutex_unlock(&devices_mutex);
	return err;
}