static int ff800_begin_session(struct snd_ff *ff, unsigned int rate) { __le32 reg; int err; reg = cpu_to_le32(rate); err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, FF800_STF, ®, sizeof(reg), 0); if (err < 0) return err; // If starting isochronous communication immediately, change of STF has // no effect. In this case, the communication runs based on former STF. // Let's sleep for a bit. msleep(100); err = allocate_rx_resources(ff); if (err < 0) return err; err = allocate_tx_resources(ff); if (err < 0) return err; reg = cpu_to_le32(0x80000000); reg |= cpu_to_le32(ff->tx_stream.data_block_quadlets); if (fw_parent_device(ff->unit)->max_speed == SCODE_800) reg |= cpu_to_le32(FF800_TX_S800_FLAG); return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, FF800_ISOC_COMM_START, ®, sizeof(reg), 0); }
static void ff800_finish_session(struct snd_ff *ff) { __le32 reg; reg = cpu_to_le32(0x80000000); snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, FF800_ISOC_COMM_STOP, ®, sizeof(reg), 0); }
static int name_card(struct snd_oxfw *oxfw) { struct fw_device *fw_dev = fw_parent_device(oxfw->unit); const struct compat_info *info; char vendor[24]; char model[32]; const char *d, *v, *m; u32 firmware; int err; /* get vendor name from root directory */ err = fw_csr_string(fw_dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor)); if (err < 0) goto end; /* get model name from unit directory */ err = fw_csr_string(oxfw->unit->directory, CSR_MODEL, model, sizeof(model)); if (err < 0) goto end; err = snd_fw_transaction(oxfw->unit, TCODE_READ_QUADLET_REQUEST, OXFORD_FIRMWARE_ID_ADDRESS, &firmware, 4, 0); if (err < 0) goto end; be32_to_cpus(&firmware); /* to apply card definitions */ if (oxfw->entry->vendor_id == VENDOR_GRIFFIN || oxfw->entry->vendor_id == VENDOR_LACIE) { info = (const struct compat_info *)oxfw->entry->driver_data; d = info->driver_name; v = info->vendor_name; m = info->model_name; } else { d = "OXFW"; v = vendor; m = model; } strcpy(oxfw->card->driver, d); strcpy(oxfw->card->mixername, m); strcpy(oxfw->card->shortname, m); snprintf(oxfw->card->longname, sizeof(oxfw->card->longname), "%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d", v, m, firmware >> 20, firmware & 0xffff, fw_dev->config_rom[3], fw_dev->config_rom[4], dev_name(&oxfw->unit->device), 100 << fw_dev->max_speed); end: return err; }
static int allocate_tx_resources(struct snd_ff *ff) { __le32 reg; unsigned int count; unsigned int tx_isoc_channel; int err; reg = cpu_to_le32(ff->tx_stream.data_block_quadlets); err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, FF800_ALLOC_TX_STREAM, ®, sizeof(reg), 0); if (err < 0) return err; // Wait till the format of tx packet is available. count = 0; while (count++ < 10) { u32 data; err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, FF800_TX_PACKET_ISOC_CH, ®, sizeof(reg), 0); if (err < 0) return err; data = le32_to_cpu(reg); if (data != 0xffffffff) { tx_isoc_channel = data; break; } msleep(50); } if (count >= 10) return -ETIMEDOUT; // NOTE: this is a makeshift to start OHCI 1394 IR context in the // channel. On the other hand, 'struct fw_iso_resources.allocated' is // not true and it's not deallocated at stop. ff->tx_resources.channel = tx_isoc_channel; return 0; }
static int get_optical_iface_mode(struct snd_dg00x *dg00x, enum snd_dg00x_optical_mode *mode) { __be32 data; int err; err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, DG00X_ADDR_BASE + DG00X_OFFSET_OPT_IFACE_MODE, &data, sizeof(data), 0); if (err >= 0) *mode = be32_to_cpu(data) & 0x01; return err; }
static int allocate_rx_resources(struct snd_ff *ff) { u32 data; __le32 reg; int err; // Controllers should allocate isochronous resources for rx stream. err = fw_iso_resources_allocate(&ff->rx_resources, amdtp_stream_get_max_payload(&ff->rx_stream), fw_parent_device(ff->unit)->max_speed); if (err < 0) return err; // Set isochronous channel and the number of quadlets of rx packets. data = ff->rx_stream.data_block_quadlets << 3; data = (data << 8) | ff->rx_resources.channel; reg = cpu_to_le32(data); return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, FF800_RX_PACKET_FORMAT, ®, sizeof(reg), 0); }