Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / wl12xx / wl1271_boot.c
index 41c6aff..1a36d8a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of wl1271
  *
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Nokia Corporation
  *
  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
  *
@@ -22,6 +22,7 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/slab.h>
 
 #include "wl1271_acx.h"
 #include "wl1271_reg.h"
@@ -350,7 +351,7 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl)
 static int wl1271_boot_run_firmware(struct wl1271 *wl)
 {
        int loop, ret;
-       u32 chip_id, interrupt;
+       u32 chip_id, intr;
 
        wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
 
@@ -367,15 +368,15 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
        loop = 0;
        while (loop++ < INIT_LOOP) {
                udelay(INIT_LOOP_DELAY);
-               interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+               intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 
-               if (interrupt == 0xffffffff) {
+               if (intr == 0xffffffff) {
                        wl1271_error("error reading hardware complete "
                                     "init indication");
                        return -EIO;
                }
                /* check that ACX_INTR_INIT_COMPLETE is enabled */
-               else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
+               else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
                        wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
                                       WL1271_ACX_INTR_INIT_COMPLETE);
                        break;
@@ -410,7 +411,10 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
        /* unmask required mbox events  */
        wl->event_mask = BSS_LOSE_EVENT_ID |
                SCAN_COMPLETE_EVENT_ID |
-               PS_REPORT_EVENT_ID;
+               PS_REPORT_EVENT_ID |
+               JOIN_EVENT_COMPLETE_ID |
+               DISCONNECT_EVENT_COMPLETE_ID |
+               RSSI_SNR_TRIGGER_0_EVENT_ID;
 
        ret = wl1271_event_unmask(wl);
        if (ret < 0) {
@@ -437,11 +441,23 @@ static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
        return 0;
 }
 
+static void wl1271_boot_hw_version(struct wl1271 *wl)
+{
+       u32 fuse;
+
+       fuse = wl1271_top_reg_read(wl, REG_FUSE_DATA_2_1);
+       fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET;
+
+       wl->hw_pg_ver = (s8)fuse;
+}
+
 int wl1271_boot(struct wl1271 *wl)
 {
        int ret = 0;
        u32 tmp, clk, pause;
 
+       wl1271_boot_hw_version(wl);
+
        if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
                /* ref clk: 19.2/38.4/38.4-XTAL */
                clk = 0x3;
@@ -451,11 +467,15 @@ int wl1271_boot(struct wl1271 *wl)
 
        if (REF_CLOCK != 0) {
                u16 val;
-               /* Set clock type */
+               /* Set clock type (open drain) */
                val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
                val &= FREF_CLK_TYPE_BITS;
-               val |= CLK_REQ_PRCM;
                wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
+
+               /* Set clock pull mode (no pull) */
+               val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
+               val |= NO_PULL;
+               wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
        } else {
                u16 val;
                /* Set clock polarity */