bool    disabled;
 };
 
+struct ocp_attr_group {
+       u64 cap;
+       const struct attribute_group *group;
+};
+
+#define OCP_CAP_BASIC  BIT(0)
+
 #define OCP_BOARD_ID_LEN               13
 #define OCP_SERIAL_LEN                 6
 
        struct platform_device  *spi_flash;
        struct clk_hw           *i2c_clk;
        struct timer_list       watchdog;
+       const struct ocp_attr_group *attr_tbl;
        const struct ptp_ocp_eeprom_map *eeprom_map;
        struct dentry           *debug_root;
        time64_t                gnss_lost;
        int                     flash_start;
        u32                     utc_tai_offset;
        u32                     ts_window_adjust;
+       u64                     fw_cap;
        struct ptp_ocp_sma_connector sma[4];
 };
 
 static irqreturn_t ptp_ocp_ts_irq(int irq, void *priv);
 static int ptp_ocp_ts_enable(void *priv, u32 req, bool enable);
 
+static const struct ocp_attr_group fb_timecard_groups[];
+
 struct ptp_ocp_eeprom_map {
        u16     off;
        u16     len;
        bp->flash_start = 1024 * 4096;
        bp->eeprom_map = fb_eeprom_map;
        bp->fw_version = ioread32(&bp->image->version);
+       bp->attr_tbl = fb_timecard_groups;
+       bp->fw_cap = OCP_CAP_BASIC;
 
        ptp_ocp_tod_init(bp);
        ptp_ocp_nmea_out_init(bp);
 }
 static DEVICE_ATTR_RW(tod_correction);
 
-static struct attribute *timecard_attrs[] = {
+static struct attribute *fb_timecard_attrs[] = {
        &dev_attr_serialnum.attr,
        &dev_attr_gnss_sync.attr,
        &dev_attr_clock_source.attr,
        &dev_attr_tod_correction.attr,
        NULL,
 };
-ATTRIBUTE_GROUPS(timecard);
+static const struct attribute_group fb_timecard_group = {
+       .attrs = fb_timecard_attrs,
+};
+static const struct ocp_attr_group fb_timecard_groups[] = {
+       { .cap = OCP_CAP_BASIC,     .group = &fb_timecard_group },
+       { },
+};
 
 static void
 gpio_input_map(char *buf, struct ptp_ocp *bp, u16 map[][2], u16 bit,
 {
        struct pps_device *pps;
        char buf[32];
+       int i, err;
 
        if (bp->gnss_port != -1) {
                sprintf(buf, "ttyS%d", bp->gnss_port);
        if (pps)
                ptp_ocp_symlink(bp, pps->dev, "pps");
 
-       if (device_add_groups(&bp->dev, timecard_groups))
-               pr_err("device add groups failed\n");
+       for (i = 0; bp->attr_tbl[i].cap; i++) {
+               if (!(bp->attr_tbl[i].cap & bp->fw_cap))
+                       continue;
+               err = sysfs_create_group(&bp->dev.kobj, bp->attr_tbl[i].group);
+               if (err)
+                       return err;
+       }
 
        ptp_ocp_debugfs_add_device(bp);
 
 ptp_ocp_detach_sysfs(struct ptp_ocp *bp)
 {
        struct device *dev = &bp->dev;
+       int i;
 
        sysfs_remove_link(&dev->kobj, "ttyGNSS");
        sysfs_remove_link(&dev->kobj, "ttyMAC");
        sysfs_remove_link(&dev->kobj, "ptp");
        sysfs_remove_link(&dev->kobj, "pps");
-       device_remove_groups(dev, timecard_groups);
+       if (bp->attr_tbl)
+               for (i = 0; bp->attr_tbl[i].cap; i++)
+                       sysfs_remove_group(&dev->kobj, bp->attr_tbl[i].group);
 }
 
 static void