Skip to content

Commit

Permalink
ALSA: oxfw: allocate own address region for SCS.1 series
Browse files Browse the repository at this point in the history
When physical controls on SCS.1 models are operated, the models transfer
MIDI messages in asynchronous transactions on IEEE 1394 bus. The models
have a register to have an address for the transactions, and drivers
can register own address for this purpose.

This commit keeps a region of address, registers it and adds a handler for
the transactions.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Sakamoto authored and Takashi Iwai committed Dec 22, 2015
1 parent 3f47152 commit e3315b4
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
65 changes: 64 additions & 1 deletion sound/firewire/oxfw/oxfw-scs1x.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,81 @@

#include "oxfw.h"

#define HSS1394_ADDRESS 0xc007dedadadaULL
#define HSS1394_MAX_PACKET_SIZE 64
#define HSS1394_TAG_CHANGE_ADDRESS 0xf1

struct fw_scs1x {
struct fw_address_handler hss_handler;
};

static void handle_hss(struct fw_card *card, struct fw_request *request,
int tcode, int destination, int source, int generation,
unsigned long long offset, void *data, size_t length,
void *callback_data)
{
fw_send_response(card, request, RCODE_COMPLETE);
}

static int register_address(struct snd_oxfw *oxfw)
{
struct fw_scs1x *scs = oxfw->spec;
__be64 data;

data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
scs->hss_handler.offset);
return snd_fw_transaction(oxfw->unit, TCODE_WRITE_BLOCK_REQUEST,
HSS1394_ADDRESS, &data, sizeof(data), 0);
}

static void remove_scs1x(struct snd_rawmidi *rmidi)
{
struct fw_scs1x *scs = rmidi->private_data;

fw_core_remove_address_handler(&scs->hss_handler);
}

void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw)
{
register_address(oxfw);
}

int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw)
{
struct snd_rawmidi *rmidi;
struct fw_scs1x *scs;
int err;

scs = kzalloc(sizeof(struct fw_scs1x), GFP_KERNEL);
if (scs == NULL)
return -ENOMEM;
oxfw->spec = scs;

/* Allocate own handler for imcoming asynchronous transaction. */
scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE;
scs->hss_handler.address_callback = handle_hss;
scs->hss_handler.callback_data = scs;
err = fw_core_add_address_handler(&scs->hss_handler,
&fw_high_memory_region);
if (err < 0)
return err;

err = register_address(oxfw);
if (err < 0)
goto err_allocated;

/* Use unique name for backward compatibility to scs1x module. */
err = snd_rawmidi_new(oxfw->card, "SCS.1x", 0, 0, 0, &rmidi);
if (err < 0)
return err;
goto err_allocated;
rmidi->private_data = scs;
rmidi->private_free = remove_scs1x;

snprintf(rmidi->name, sizeof(rmidi->name),
"%s MIDI", oxfw->card->shortname);

return 0;
err_allocated:
fw_core_remove_address_handler(&scs->hss_handler);
return err;
}
1 change: 1 addition & 0 deletions sound/firewire/oxfw/oxfw.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@ int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw);

int snd_oxfw_add_spkr(struct snd_oxfw *oxfw, bool is_lacie);
int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw);
void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw);

0 comments on commit e3315b4

Please sign in to comment.