diff options
Diffstat (limited to 'driver/hdm-usb/hdm_usb.c')
-rw-r--r-- | driver/hdm-usb/hdm_usb.c | 146 |
1 files changed, 88 insertions, 58 deletions
diff --git a/driver/hdm-usb/hdm_usb.c b/driver/hdm-usb/hdm_usb.c index 8c88184..9ab744b 100644 --- a/driver/hdm-usb/hdm_usb.c +++ b/driver/hdm-usb/hdm_usb.c @@ -79,10 +79,12 @@ struct buf_anchor { * struct most_dci_obj - Direct Communication Interface * @kobj:position in sysfs * @usb_device: pointer to the usb device + * @reg_addr: register address for arbitrary DCI access */ struct most_dci_obj { struct kobject kobj; struct usb_device *usb_device; + u16 reg_addr; }; #define to_dci_obj(p) container_of(p, struct most_dci_obj, kobj) @@ -324,10 +326,10 @@ static int hdm_poison_channel(struct most_interface *iface, int channel) static int hdm_add_padding(struct most_dev *mdev, int channel, struct mbo *mbo) { struct most_channel_config *conf = &mdev->conf[channel]; - unsigned int j, num_frames, frame_size; + unsigned int frame_size = get_stream_frame_size(conf); + unsigned int j, num_frames; u16 rd_addr, wr_addr; - frame_size = get_stream_frame_size(conf); if (!frame_size) return -EIO; num_frames = mbo->buffer_length / frame_size; @@ -361,10 +363,10 @@ static int hdm_add_padding(struct most_dev *mdev, int channel, struct mbo *mbo) static int hdm_remove_padding(struct most_dev *mdev, int channel, struct mbo *mbo) { - unsigned int j, num_frames, frame_size; struct most_channel_config *const conf = &mdev->conf[channel]; + unsigned int frame_size = get_stream_frame_size(conf); + unsigned int j, num_frames; - frame_size = get_stream_frame_size(conf); if (!frame_size) return -EIO; num_frames = mbo->processed_length / USB_MTU; @@ -801,17 +803,17 @@ static int hdm_update_netinfo(struct most_dev *mdev) if (!is_valid_ether_addr(mdev->hw_addr)) { if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_HI, &hi) < 0) { dev_err(dev, "Vendor request \"hw_addr_hi\" failed\n"); - return -1; + return -EFAULT; } if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_MI, &mi) < 0) { dev_err(dev, "Vendor request \"hw_addr_mid\" failed\n"); - return -1; + return -EFAULT; } if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_LO, &lo) < 0) { dev_err(dev, "Vendor request \"hw_addr_low\" failed\n"); - return -1; + return -EFAULT; } mutex_lock(&mdev->io_mutex); @@ -826,7 +828,7 @@ static int hdm_update_netinfo(struct most_dev *mdev) if (drci_rd_reg(usb_device, DRCI_REG_NI_STATE, &link) < 0) { dev_err(dev, "Vendor request \"link status\" failed\n"); - return -1; + return -EFAULT; } mutex_lock(&mdev->io_mutex); @@ -950,6 +952,10 @@ static struct usb_device_id usbid[] = { struct most_dci_attribute most_dci_attr_##_name = \ __ATTR(_name, S_IRUGO | S_IWUSR, show_value, store_value) +#define MOST_DCI_WO_ATTR(_name) \ + struct most_dci_attribute most_dci_attr_##_name = \ + __ATTR(_name, S_IWUSR, NULL, store_value) + /** * struct most_dci_attribute - to access the attributes of a dci object * @attr: attributes of a dci object @@ -1026,45 +1032,68 @@ static void most_dci_release(struct kobject *kobj) kfree(dci_obj); } +struct regs { + const char *name; + u16 reg; +}; + +const static struct regs ro_regs[] = { + { "ni_state", DRCI_REG_NI_STATE }, + { "packet_bandwidth", DRCI_REG_PACKET_BW }, + { "node_address", DRCI_REG_NODE_ADDR }, + { "node_position", DRCI_REG_NODE_POS }, +}; + +const static struct regs rw_regs[] = { + { "mep_filter", DRCI_REG_MEP_FILTER }, + { "mep_hash0", DRCI_REG_HASH_TBL0 }, + { "mep_hash1", DRCI_REG_HASH_TBL1 }, + { "mep_hash2", DRCI_REG_HASH_TBL2 }, + { "mep_hash3", DRCI_REG_HASH_TBL3 }, + { "mep_eui48_hi", DRCI_REG_HW_ADDR_HI }, + { "mep_eui48_mi", DRCI_REG_HW_ADDR_MI }, + { "mep_eui48_lo", DRCI_REG_HW_ADDR_LO }, +}; + +static int get_stat_reg_addr(const struct regs *regs, int size, + const char *name, u16 *reg_addr) +{ + int i; + + for (i = 0; i < size; i++) { + if (!strcmp(name, regs[i].name)) { + *reg_addr = regs[i].reg; + return 0; + } + } + return -EFAULT; +} + +#define get_static_reg_addr(regs, name, reg_addr) \ + get_stat_reg_addr(regs, ARRAY_SIZE(regs), name, reg_addr) + static ssize_t show_value(struct most_dci_obj *dci_obj, struct most_dci_attribute *attr, char *buf) { - u16 tmp_val; + const char *name = attr->attr.name; + u16 val; u16 reg_addr; int err; - if (!strcmp(attr->attr.name, "ni_state")) - reg_addr = DRCI_REG_NI_STATE; - else if (!strcmp(attr->attr.name, "packet_bandwidth")) - reg_addr = DRCI_REG_PACKET_BW; - else if (!strcmp(attr->attr.name, "node_address")) - reg_addr = DRCI_REG_NODE_ADDR; - else if (!strcmp(attr->attr.name, "node_position")) - reg_addr = DRCI_REG_NODE_POS; - else if (!strcmp(attr->attr.name, "mep_filter")) - reg_addr = DRCI_REG_MEP_FILTER; - else if (!strcmp(attr->attr.name, "mep_hash0")) - reg_addr = DRCI_REG_HASH_TBL0; - else if (!strcmp(attr->attr.name, "mep_hash1")) - reg_addr = DRCI_REG_HASH_TBL1; - else if (!strcmp(attr->attr.name, "mep_hash2")) - reg_addr = DRCI_REG_HASH_TBL2; - else if (!strcmp(attr->attr.name, "mep_hash3")) - reg_addr = DRCI_REG_HASH_TBL3; - else if (!strcmp(attr->attr.name, "mep_eui48_hi")) - reg_addr = DRCI_REG_HW_ADDR_HI; - else if (!strcmp(attr->attr.name, "mep_eui48_mi")) - reg_addr = DRCI_REG_HW_ADDR_MI; - else if (!strcmp(attr->attr.name, "mep_eui48_lo")) - reg_addr = DRCI_REG_HW_ADDR_LO; - else - return -EIO; + if (!strcmp(name, "arb_address")) + return snprintf(buf, PAGE_SIZE, "%04x\n", dci_obj->reg_addr); + + if (!strcmp(name, "arb_value")) + reg_addr = dci_obj->reg_addr; + else if (get_static_reg_addr(ro_regs, name, ®_addr) && + get_static_reg_addr(rw_regs, name, ®_addr)) + return -EFAULT; - err = drci_rd_reg(dci_obj->usb_device, reg_addr, &tmp_val); + err = drci_rd_reg(dci_obj->usb_device, reg_addr, &val); if (err < 0) return err; - return snprintf(buf, PAGE_SIZE, "%04x\n", tmp_val); + return snprintf(buf, PAGE_SIZE, "%04x\n", val); } static ssize_t store_value(struct most_dci_obj *dci_obj, @@ -1073,31 +1102,26 @@ static ssize_t store_value(struct most_dci_obj *dci_obj, { u16 val; u16 reg_addr; - int err; - - if (!strcmp(attr->attr.name, "mep_filter")) - reg_addr = DRCI_REG_MEP_FILTER; - else if (!strcmp(attr->attr.name, "mep_hash0")) - reg_addr = DRCI_REG_HASH_TBL0; - else if (!strcmp(attr->attr.name, "mep_hash1")) - reg_addr = DRCI_REG_HASH_TBL1; - else if (!strcmp(attr->attr.name, "mep_hash2")) - reg_addr = DRCI_REG_HASH_TBL2; - else if (!strcmp(attr->attr.name, "mep_hash3")) - reg_addr = DRCI_REG_HASH_TBL3; - else if (!strcmp(attr->attr.name, "mep_eui48_hi")) - reg_addr = DRCI_REG_HW_ADDR_HI; - else if (!strcmp(attr->attr.name, "mep_eui48_mi")) - reg_addr = DRCI_REG_HW_ADDR_MI; - else if (!strcmp(attr->attr.name, "mep_eui48_lo")) - reg_addr = DRCI_REG_HW_ADDR_LO; - else - return -EIO; + const char *name = attr->attr.name; + int err = kstrtou16(buf, 16, &val); - err = kstrtou16(buf, 16, &val); if (err) return err; + if (!strcmp(name, "arb_address")) { + dci_obj->reg_addr = val; + return count; + } + + if (!strcmp(name, "arb_value")) { + reg_addr = dci_obj->reg_addr; + } else if (!strcmp(name, "sync_ep")) { + reg_addr = DRCI_REG_BASE + DRCI_COMMAND + val * 16; + val = 1; + } else if (get_static_reg_addr(ro_regs, name, ®_addr)) { + return -EFAULT; + } + err = drci_wr_reg(dci_obj->usb_device, reg_addr, val); if (err < 0) return err; @@ -1109,6 +1133,7 @@ static MOST_DCI_RO_ATTR(ni_state); static MOST_DCI_RO_ATTR(packet_bandwidth); static MOST_DCI_RO_ATTR(node_address); static MOST_DCI_RO_ATTR(node_position); +static MOST_DCI_WO_ATTR(sync_ep); static MOST_DCI_ATTR(mep_filter); static MOST_DCI_ATTR(mep_hash0); static MOST_DCI_ATTR(mep_hash1); @@ -1117,6 +1142,8 @@ static MOST_DCI_ATTR(mep_hash3); static MOST_DCI_ATTR(mep_eui48_hi); static MOST_DCI_ATTR(mep_eui48_mi); static MOST_DCI_ATTR(mep_eui48_lo); +static MOST_DCI_ATTR(arb_address); +static MOST_DCI_ATTR(arb_value); /** * most_dci_def_attrs - array of default attribute files of the dci object @@ -1126,6 +1153,7 @@ static struct attribute *most_dci_def_attrs[] = { &most_dci_attr_packet_bandwidth.attr, &most_dci_attr_node_address.attr, &most_dci_attr_node_position.attr, + &most_dci_attr_sync_ep.attr, &most_dci_attr_mep_filter.attr, &most_dci_attr_mep_hash0.attr, &most_dci_attr_mep_hash1.attr, @@ -1134,6 +1162,8 @@ static struct attribute *most_dci_def_attrs[] = { &most_dci_attr_mep_eui48_hi.attr, &most_dci_attr_mep_eui48_mi.attr, &most_dci_attr_mep_eui48_lo.attr, + &most_dci_attr_arb_address.attr, + &most_dci_attr_arb_value.attr, NULL, }; |