#include <linux/device.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
#include <linux/module.h>
#include "iso-resources.h"
#define MPR_SPEED_MASK 0xc0000000
#define MPR_SPEED_SHIFT 30
#define MPR_XSPEED_MASK 0x00000060
#define MPR_XSPEED_SHIFT 5
#define MPR_PLUGS_MASK 0x0000001f
#define PCR_ONLINE 0x80000000
#define PCR_BCAST_CONN 0x40000000
#define PCR_P2P_CONN_MASK 0x3f000000
#define PCR_P2P_CONN_SHIFT 24
#define PCR_CHANNEL_MASK 0x003f0000
#define PCR_CHANNEL_SHIFT 16
#define OPCR_XSPEED_MASK 0x00C00000
#define OPCR_XSPEED_SHIFT 22
#define OPCR_SPEED_MASK 0x0000C000
#define OPCR_SPEED_SHIFT 14
#define OPCR_OVERHEAD_ID_MASK 0x00003C00
#define OPCR_OVERHEAD_ID_SHIFT 10
enum bus_reset_handling {
void cmp_error(struct cmp_connection *c, const char *fmt, ...)
dev_err(&c->resources.unit->device, "%cPCR%u: %pV",
(c->direction == CMP_INPUT) ? 'i' : 'o',
c->pcr_index, &(struct va_format){ fmt, &va });
static u64 mpr_address(struct cmp_connection *c)
if (c->direction == CMP_INPUT)
return CSR_REGISTER_BASE + CSR_IMPR;
return CSR_REGISTER_BASE + CSR_OMPR;
static u64 pcr_address(struct cmp_connection *c)
if (c->direction == CMP_INPUT)
return CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index);
return CSR_REGISTER_BASE + CSR_OPCR(c->pcr_index);
static int pcr_modify(struct cmp_connection *c,
__be32 (*modify)(struct cmp_connection *c, __be32 old),
int (*check)(struct cmp_connection *c, __be32 pcr),
enum bus_reset_handling bus_reset_handling)
__be32 old_arg, buffer[2];
buffer[0] = c->last_pcr_value;
buffer[1] = modify(c, buffer[0]);
err = snd_fw_transaction(
c->resources.unit, TCODE_LOCK_COMPARE_SWAP,
pcr_address(c), buffer, 8,
FW_FIXED_GENERATION | c->resources.generation);