/drivers/net/wireless/wl12xx/io.c
C | 183 lines | 92 code | 26 blank | 65 comment | 9 complexity | f7cb580ab3375f962d6d7bc6d1c16e07 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
1/* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2008-2010 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 * 22 */ 23 24#include <linux/module.h> 25#include <linux/platform_device.h> 26#include <linux/spi/spi.h> 27 28#include "wl12xx.h" 29#include "wl12xx_80211.h" 30#include "io.h" 31#include "tx.h" 32 33#define OCP_CMD_LOOP 32 34 35#define OCP_CMD_WRITE 0x1 36#define OCP_CMD_READ 0x2 37 38#define OCP_READY_MASK BIT(18) 39#define OCP_STATUS_MASK (BIT(16) | BIT(17)) 40 41#define OCP_STATUS_NO_RESP 0x00000 42#define OCP_STATUS_OK 0x10000 43#define OCP_STATUS_REQ_FAILED 0x20000 44#define OCP_STATUS_RESP_ERROR 0x30000 45 46bool wl1271_set_block_size(struct wl1271 *wl) 47{ 48 if (wl->if_ops->set_block_size) { 49 wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE); 50 return true; 51 } 52 53 return false; 54} 55 56void wl1271_disable_interrupts(struct wl1271 *wl) 57{ 58 wl->if_ops->disable_irq(wl); 59} 60 61void wl1271_enable_interrupts(struct wl1271 *wl) 62{ 63 wl->if_ops->enable_irq(wl); 64} 65 66/* Set the SPI partitions to access the chip addresses 67 * 68 * To simplify driver code, a fixed (virtual) memory map is defined for 69 * register and memory addresses. Because in the chipset, in different stages 70 * of operation, those addresses will move around, an address translation 71 * mechanism is required. 72 * 73 * There are four partitions (three memory and one register partition), 74 * which are mapped to two different areas of the hardware memory. 75 * 76 * Virtual address 77 * space 78 * 79 * | | 80 * ...+----+--> mem.start 81 * Physical address ... | | 82 * space ... | | [PART_0] 83 * ... | | 84 * 00000000 <--+----+... ...+----+--> mem.start + mem.size 85 * | | ... | | 86 * |MEM | ... | | 87 * | | ... | | 88 * mem.size <--+----+... | | {unused area) 89 * | | ... | | 90 * |REG | ... | | 91 * mem.size | | ... | | 92 * + <--+----+... ...+----+--> reg.start 93 * reg.size | | ... | | 94 * |MEM2| ... | | [PART_1] 95 * | | ... | | 96 * ...+----+--> reg.start + reg.size 97 * | | 98 * 99 */ 100int wl1271_set_partition(struct wl1271 *wl, 101 struct wl1271_partition_set *p) 102{ 103 /* copy partition info */ 104 memcpy(&wl->part, p, sizeof(*p)); 105 106 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", 107 p->mem.start, p->mem.size); 108 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", 109 p->reg.start, p->reg.size); 110 wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", 111 p->mem2.start, p->mem2.size); 112 wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", 113 p->mem3.start, p->mem3.size); 114 115 /* write partition info to the chipset */ 116 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); 117 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); 118 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); 119 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); 120 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); 121 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); 122 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); 123 124 return 0; 125} 126EXPORT_SYMBOL_GPL(wl1271_set_partition); 127 128void wl1271_io_reset(struct wl1271 *wl) 129{ 130 if (wl->if_ops->reset) 131 wl->if_ops->reset(wl); 132} 133 134void wl1271_io_init(struct wl1271 *wl) 135{ 136 if (wl->if_ops->init) 137 wl->if_ops->init(wl); 138} 139 140void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) 141{ 142 /* write address >> 1 + 0x30000 to OCP_POR_CTR */ 143 addr = (addr >> 1) + 0x30000; 144 wl1271_write32(wl, OCP_POR_CTR, addr); 145 146 /* write value to OCP_POR_WDATA */ 147 wl1271_write32(wl, OCP_DATA_WRITE, val); 148 149 /* write 1 to OCP_CMD */ 150 wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE); 151} 152 153u16 wl1271_top_reg_read(struct wl1271 *wl, int addr) 154{ 155 u32 val; 156 int timeout = OCP_CMD_LOOP; 157 158 /* write address >> 1 + 0x30000 to OCP_POR_CTR */ 159 addr = (addr >> 1) + 0x30000; 160 wl1271_write32(wl, OCP_POR_CTR, addr); 161 162 /* write 2 to OCP_CMD */ 163 wl1271_write32(wl, OCP_CMD, OCP_CMD_READ); 164 165 /* poll for data ready */ 166 do { 167 val = wl1271_read32(wl, OCP_DATA_READ); 168 } while (!(val & OCP_READY_MASK) && --timeout); 169 170 if (!timeout) { 171 wl1271_warning("Top register access timed out."); 172 return 0xffff; 173 } 174 175 /* check data status and return if OK */ 176 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) 177 return val & 0xffff; 178 else { 179 wl1271_warning("Top register access returned error."); 180 return 0xffff; 181 } 182} 183