#include "reg.h"
 
-static struct wlcore_ops wl12xx_ops = {
-};
-
 static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
        [PART_DOWN] = {
                .mem = {
        [REG_RAW_FW_STATUS_ADDR]        = FW_STATUS_ADDR,
 };
 
+/* TODO: maybe move to a new header file? */
+#define WL127X_FW_NAME_MULTI   "ti-connectivity/wl127x-fw-4-mr.bin"
+#define WL127X_FW_NAME_SINGLE  "ti-connectivity/wl127x-fw-4-sr.bin"
+#define WL127X_PLT_FW_NAME     "ti-connectivity/wl127x-fw-4-plt.bin"
+
+#define WL128X_FW_NAME_MULTI   "ti-connectivity/wl128x-fw-4-mr.bin"
+#define WL128X_FW_NAME_SINGLE  "ti-connectivity/wl128x-fw-4-sr.bin"
+#define WL128X_PLT_FW_NAME     "ti-connectivity/wl128x-fw-4-plt.bin"
+
+static int wl12xx_identify_chip(struct wl1271 *wl)
+{
+       int ret = 0;
+
+       switch (wl->chip.id) {
+       case CHIP_ID_1271_PG10:
+               wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
+                              wl->chip.id);
+
+               wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
+               wl->plt_fw_name = WL127X_PLT_FW_NAME;
+               wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
+               wl->mr_fw_name = WL127X_FW_NAME_MULTI;
+               break;
+
+       case CHIP_ID_1271_PG20:
+               wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
+                            wl->chip.id);
+
+               wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
+               wl->plt_fw_name = WL127X_PLT_FW_NAME;
+               wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
+               wl->mr_fw_name = WL127X_FW_NAME_MULTI;
+               break;
+
+       case CHIP_ID_1283_PG20:
+               wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
+                            wl->chip.id);
+               wl->plt_fw_name = WL128X_PLT_FW_NAME;
+               wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
+               wl->mr_fw_name = WL128X_FW_NAME_MULTI;
+               break;
+       case CHIP_ID_1283_PG10:
+       default:
+               wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
+               ret = -ENODEV;
+               goto out;
+       }
+
+out:
+       return ret;
+}
+
+static struct wlcore_ops wl12xx_ops = {
+       .identify_chip = wl12xx_identify_chip,
+};
+
 static int __devinit wl12xx_probe(struct platform_device *pdev)
 {
        struct wl1271 *wl;
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
+MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
+MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
+MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
+MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
+MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
+MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
 
 #define CLK_REQ_OUTN_SEL       0x700
 
 #define WU_COUNTER_PAUSE_VAL 0x3FF
-#define WELP_ARM_COMMAND_VAL 0x4
 
 /* PLL configuration algorithm for wl128x */
 #define SYS_CLK_CFG_REG              0x2200
 
        /* Only new station firmwares support routing fw logs to the host */
        if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
            (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
-               quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
+               quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
 
        /* This feature is not yet supported for AP mode */
        if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
-               quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
+               quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
 
        return quirks;
 }
        u32 clk;
 
        if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
-               wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
+               wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
 
        if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
            wl->ref_clock == CONF_REF_CLK_38_4_E ||
 
 {
        int ret;
 
-       if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED)
+       if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
                return 0;
 
        ret = wl12xx_cmd_config_fwlog(wl);
        if (wl->chip.id == CHIP_ID_1283_PG20) {
                u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
 
-               if (!(wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT))
+               if (!(wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT))
                        /* Enable SDIO padding */
                        host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
 
 
 
        if (plt) {
                fw_type = WL12XX_FW_TYPE_PLT;
-               if (wl->chip.id == CHIP_ID_1283_PG20)
-                       fw_name = WL128X_PLT_FW_NAME;
-               else
-                       fw_name = WL127X_PLT_FW_NAME;
+               fw_name = wl->plt_fw_name;
        } else {
                /*
                 * we can't call wl12xx_get_vif_count() here because
                 */
                if (wl->last_vif_count > 1) {
                        fw_type = WL12XX_FW_TYPE_MULTI;
-                       if (wl->chip.id == CHIP_ID_1283_PG20)
-                               fw_name = WL128X_FW_NAME_MULTI;
-                       else
-                               fw_name = WL127X_FW_NAME_MULTI;
+                       fw_name = wl->mr_fw_name;
                } else {
                        fw_type = WL12XX_FW_TYPE_NORMAL;
-                       if (wl->chip.id == CHIP_ID_1283_PG20)
-                               fw_name = WL128X_FW_NAME_SINGLE;
-                       else
-                               fw_name = WL127X_FW_NAME_SINGLE;
+                       fw_name = wl->sr_fw_name;
                }
        }
 
        u32 first_addr;
        u8 *block;
 
-       if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
+       if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
            (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
            (wl->conf.fwlog.mem_blocks == 0))
                return;
         * chip types.
         */
        if (!wl1271_set_block_size(wl))
-               wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
-
-       switch (wl->chip.id) {
-       case CHIP_ID_1271_PG10:
-               wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
-                              wl->chip.id);
+               wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
 
-               ret = wl1271_setup(wl);
-               if (ret < 0)
-                       goto out;
-               wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
-               break;
-
-       case CHIP_ID_1271_PG20:
-               wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
-                            wl->chip.id);
-
-               ret = wl1271_setup(wl);
-               if (ret < 0)
-                       goto out;
-               wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
-               break;
+       ret = wl->ops->identify_chip(wl);
+       if (ret < 0)
+               goto out;
 
-       case CHIP_ID_1283_PG20:
-               wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
-                            wl->chip.id);
+       /* TODO: make sure the lower driver has set things up correctly */
 
-               ret = wl1271_setup(wl);
-               if (ret < 0)
-                       goto out;
-               break;
-       case CHIP_ID_1283_PG10:
-       default:
-               wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
-               ret = -ENODEV;
+       ret = wl1271_setup(wl);
+       if (ret < 0)
                goto out;
-       }
 
        ret = wl12xx_fetch_firmware(wl, plt);
        if (ret < 0)
 
         * Write the driver's packet counter to the FW. This is only required
         * for older hardware revisions
         */
-       if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION)
+       if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
                wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER,
                               wl->rx_counter);
 
 
 static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
                                                unsigned int packet_length)
 {
-       if (wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
+       if (wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
                return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
        else
                return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
                 * Interrupt the firmware with the new packets. This is only
                 * required for older hardware revisions
                 */
-               if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION)
+               if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
                        wl1271_write32(wl, WL12XX_HOST_WR_ACCESS,
                                       wl->tx_packets_count);
 
 
 #define HW_BG_RATES_MASK       0xffff
 #define HW_HT_RATES_OFFSET     16
 
-/* Quirks */
-
-/* Each RX/TX transaction requires an end-of-transaction transfer */
-#define WL12XX_QUIRK_END_OF_TRANSACTION                BIT(0)
-
-/* wl127x and SPI don't support SDIO block size alignment */
-#define WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT    BIT(2)
-
-/* Older firmwares did not implement the FW logger over bus feature */
-#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED     BIT(4)
-
 #define WL12XX_HW_BLOCK_SIZE   256
 
 #endif
 
 #include "event.h"
 
 struct wlcore_ops {
+       int (*identify_chip)(struct wl1271 *wl);
 };
 
 enum wlcore_partitions {
        const struct wlcore_partition_set *ptable;
        /* pointer to the lower driver register table */
        const int *rtable;
+       /* name of the firmwares to load - for PLT, single role, multi-role */
+       const char *plt_fw_name;
+       const char *sr_fw_name;
+       const char *mr_fw_name;
 };
 
 int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
 /* Firmware image load chunk size */
 #define CHUNK_SIZE     16384
 
+/* Quirks */
+
+/* Each RX/TX transaction requires an end-of-transaction transfer */
+#define WLCORE_QUIRK_END_OF_TRANSACTION                BIT(0)
+
+/* wl127x and SPI don't support SDIO block size alignment */
+#define WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT    BIT(2)
+
+/* Older firmwares did not implement the FW logger over bus feature */
+#define WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED     BIT(4)
+
 /* TODO: move to the lower drivers when all usages are abstracted */
 #define CHIP_ID_1271_PG10              (0x4030101)
 #define CHIP_ID_1271_PG20              (0x4030111)
 
 #define ECPU_CONTROL_HALT      0x00000101
 
+#define WELP_ARM_COMMAND_VAL   0x4
+
 #endif /* __WLCORE_H__ */