cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

motu.c (5357B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * motu.c - a part of driver for MOTU FireWire series
      4 *
      5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
      6 */
      7
      8#include "motu.h"
      9
     10#define OUI_MOTU	0x0001f2
     11
     12MODULE_DESCRIPTION("MOTU FireWire driver");
     13MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
     14MODULE_LICENSE("GPL v2");
     15
     16const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT] = {
     17	/* mode 0 */
     18	[0] =  44100,
     19	[1] =  48000,
     20	/* mode 1 */
     21	[2] =  88200,
     22	[3] =  96000,
     23	/* mode 2 */
     24	[4] = 176400,
     25	[5] = 192000,
     26};
     27
     28static void name_card(struct snd_motu *motu)
     29{
     30	struct fw_device *fw_dev = fw_parent_device(motu->unit);
     31	struct fw_csr_iterator it;
     32	int key, val;
     33	u32 version = 0;
     34
     35	fw_csr_iterator_init(&it, motu->unit->directory);
     36	while (fw_csr_iterator_next(&it, &key, &val)) {
     37		switch (key) {
     38		case CSR_MODEL:
     39			version = val;
     40			break;
     41		}
     42	}
     43
     44	strcpy(motu->card->driver, "FW-MOTU");
     45	strcpy(motu->card->shortname, motu->spec->name);
     46	strcpy(motu->card->mixername, motu->spec->name);
     47	snprintf(motu->card->longname, sizeof(motu->card->longname),
     48		 "MOTU %s (version:%06x), GUID %08x%08x at %s, S%d",
     49		 motu->spec->name, version,
     50		 fw_dev->config_rom[3], fw_dev->config_rom[4],
     51		 dev_name(&motu->unit->device), 100 << fw_dev->max_speed);
     52}
     53
     54static void motu_card_free(struct snd_card *card)
     55{
     56	struct snd_motu *motu = card->private_data;
     57
     58	snd_motu_transaction_unregister(motu);
     59	snd_motu_stream_destroy_duplex(motu);
     60
     61	mutex_destroy(&motu->mutex);
     62	fw_unit_put(motu->unit);
     63}
     64
     65static int motu_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry)
     66{
     67	struct snd_card *card;
     68	struct snd_motu *motu;
     69	int err;
     70
     71	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*motu), &card);
     72	if (err < 0)
     73		return err;
     74	card->private_free = motu_card_free;
     75
     76	motu = card->private_data;
     77	motu->unit = fw_unit_get(unit);
     78	dev_set_drvdata(&unit->device, motu);
     79	motu->card = card;
     80
     81	motu->spec = (const struct snd_motu_spec *)entry->driver_data;
     82	mutex_init(&motu->mutex);
     83	spin_lock_init(&motu->lock);
     84	init_waitqueue_head(&motu->hwdep_wait);
     85
     86	name_card(motu);
     87
     88	err = snd_motu_transaction_register(motu);
     89	if (err < 0)
     90		goto error;
     91
     92	err = snd_motu_stream_init_duplex(motu);
     93	if (err < 0)
     94		goto error;
     95
     96	snd_motu_proc_init(motu);
     97
     98	err = snd_motu_create_pcm_devices(motu);
     99	if (err < 0)
    100		goto error;
    101
    102	if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
    103	    (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) ||
    104	    (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
    105	    (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) {
    106		err = snd_motu_create_midi_devices(motu);
    107		if (err < 0)
    108			goto error;
    109	}
    110
    111	err = snd_motu_create_hwdep_device(motu);
    112	if (err < 0)
    113		goto error;
    114
    115	if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) {
    116		err = snd_motu_register_dsp_message_parser_new(motu);
    117		if (err < 0)
    118			goto error;
    119	} else if (motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP) {
    120		err = snd_motu_command_dsp_message_parser_new(motu);
    121		if (err < 0)
    122			goto error;
    123	}
    124
    125	err = snd_card_register(card);
    126	if (err < 0)
    127		goto error;
    128
    129	return 0;
    130error:
    131	snd_card_free(card);
    132	return err;
    133}
    134
    135static void motu_remove(struct fw_unit *unit)
    136{
    137	struct snd_motu *motu = dev_get_drvdata(&unit->device);
    138
    139	// Block till all of ALSA character devices are released.
    140	snd_card_free(motu->card);
    141}
    142
    143static void motu_bus_update(struct fw_unit *unit)
    144{
    145	struct snd_motu *motu = dev_get_drvdata(&unit->device);
    146
    147	/* The handler address register becomes initialized. */
    148	snd_motu_transaction_reregister(motu);
    149}
    150
    151#define SND_MOTU_DEV_ENTRY(model, data)			\
    152{							\
    153	.match_flags	= IEEE1394_MATCH_VENDOR_ID |	\
    154			  IEEE1394_MATCH_SPECIFIER_ID |	\
    155			  IEEE1394_MATCH_VERSION,	\
    156	.vendor_id	= OUI_MOTU,			\
    157	.specifier_id	= OUI_MOTU,			\
    158	.version	= model,			\
    159	.driver_data	= (kernel_ulong_t)data,		\
    160}
    161
    162static const struct ieee1394_device_id motu_id_table[] = {
    163	SND_MOTU_DEV_ENTRY(0x000001, &snd_motu_spec_828),
    164	SND_MOTU_DEV_ENTRY(0x000002, &snd_motu_spec_896),
    165	SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2),
    166	SND_MOTU_DEV_ENTRY(0x000005, &snd_motu_spec_896hd),
    167	SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler),
    168	SND_MOTU_DEV_ENTRY(0x00000d, &snd_motu_spec_ultralite),
    169	SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre),
    170	SND_MOTU_DEV_ENTRY(0x000015, &snd_motu_spec_828mk3_fw), // FireWire only.
    171	SND_MOTU_DEV_ENTRY(0x000019, &snd_motu_spec_ultralite_mk3), // FireWire only.
    172	SND_MOTU_DEV_ENTRY(0x00001b, &snd_motu_spec_traveler_mk3),
    173	SND_MOTU_DEV_ENTRY(0x000030, &snd_motu_spec_ultralite_mk3), // Hybrid.
    174	SND_MOTU_DEV_ENTRY(0x000035, &snd_motu_spec_828mk3_hybrid), // Hybrid.
    175	SND_MOTU_DEV_ENTRY(0x000033, &snd_motu_spec_audio_express),
    176	SND_MOTU_DEV_ENTRY(0x000039, &snd_motu_spec_track16),
    177	SND_MOTU_DEV_ENTRY(0x000045, &snd_motu_spec_4pre),
    178	{ }
    179};
    180MODULE_DEVICE_TABLE(ieee1394, motu_id_table);
    181
    182static struct fw_driver motu_driver = {
    183	.driver   = {
    184		.owner	= THIS_MODULE,
    185		.name	= KBUILD_MODNAME,
    186		.bus	= &fw_bus_type,
    187	},
    188	.probe    = motu_probe,
    189	.update   = motu_bus_update,
    190	.remove   = motu_remove,
    191	.id_table = motu_id_table,
    192};
    193
    194static int __init alsa_motu_init(void)
    195{
    196	return driver_register(&motu_driver.driver);
    197}
    198
    199static void __exit alsa_motu_exit(void)
    200{
    201	driver_unregister(&motu_driver.driver);
    202}
    203
    204module_init(alsa_motu_init);
    205module_exit(alsa_motu_exit);