-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 171440 b: refs/heads/master c: 8929742 h: refs/heads/master v: v3
- Loading branch information
Bartlomiej Zolnierkiewicz
authored and
John W. Linville
committed
Nov 6, 2009
1 parent
2166f7f
commit 433605f
Showing
7 changed files
with
265 additions
and
460 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 4d6f8b9f17626da48d6badc6ba259fbacc1413c3 | ||
refs/heads/master: 89297425c2104b187c25d6260a41345c491c8f18 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
/* | ||
Copyright (C) 2009 Bartlomiej Zolnierkiewicz | ||
Based on the original rt2800pci.c and rt2800usb.c: | ||
Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | ||
<http://rt2x00.serialmonkey.com> | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program; if not, write to the | ||
Free Software Foundation, Inc., | ||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
*/ | ||
|
||
/* | ||
Module: rt2800lib | ||
Abstract: rt2800 generic device routines. | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
|
||
#include "rt2x00.h" | ||
#include "rt2800lib.h" | ||
#include "rt2800.h" | ||
|
||
MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); | ||
MODULE_DESCRIPTION("rt2800 library"); | ||
MODULE_LICENSE("GPL"); | ||
|
||
/* | ||
* Register access. | ||
* All access to the CSR registers will go through the methods | ||
* rt2800_register_read and rt2800_register_write. | ||
* BBP and RF register require indirect register access, | ||
* and use the CSR registers BBPCSR and RFCSR to achieve this. | ||
* These indirect registers work with busy bits, | ||
* and we will try maximal REGISTER_BUSY_COUNT times to access | ||
* the register while taking a REGISTER_BUSY_DELAY us delay | ||
* between each attampt. When the busy bit is still set at that time, | ||
* the access attempt is considered to have failed, | ||
* and we will print an error. | ||
* The _lock versions must be used if you already hold the csr_mutex | ||
*/ | ||
#define WAIT_FOR_BBP(__dev, __reg) \ | ||
rt2800_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg)) | ||
#define WAIT_FOR_RFCSR(__dev, __reg) \ | ||
rt2800_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg)) | ||
#define WAIT_FOR_RF(__dev, __reg) \ | ||
rt2800_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg)) | ||
#define WAIT_FOR_MCU(__dev, __reg) \ | ||
rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \ | ||
H2M_MAILBOX_CSR_OWNER, (__reg)) | ||
|
||
void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, | ||
const unsigned int word, const u8 value) | ||
{ | ||
u32 reg; | ||
|
||
mutex_lock(&rt2x00dev->csr_mutex); | ||
|
||
/* | ||
* Wait until the BBP becomes available, afterwards we | ||
* can safely write the new data into the register. | ||
*/ | ||
if (WAIT_FOR_BBP(rt2x00dev, ®)) { | ||
reg = 0; | ||
rt2x00_set_field32(®, BBP_CSR_CFG_VALUE, value); | ||
rt2x00_set_field32(®, BBP_CSR_CFG_REGNUM, word); | ||
rt2x00_set_field32(®, BBP_CSR_CFG_BUSY, 1); | ||
rt2x00_set_field32(®, BBP_CSR_CFG_READ_CONTROL, 0); | ||
if (rt2x00_intf_is_pci(rt2x00dev)) | ||
rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1); | ||
|
||
rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); | ||
} | ||
|
||
mutex_unlock(&rt2x00dev->csr_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(rt2800_bbp_write); | ||
|
||
void rt2800_bbp_read(struct rt2x00_dev *rt2x00dev, | ||
const unsigned int word, u8 *value) | ||
{ | ||
u32 reg; | ||
|
||
mutex_lock(&rt2x00dev->csr_mutex); | ||
|
||
/* | ||
* Wait until the BBP becomes available, afterwards we | ||
* can safely write the read request into the register. | ||
* After the data has been written, we wait until hardware | ||
* returns the correct value, if at any time the register | ||
* doesn't become available in time, reg will be 0xffffffff | ||
* which means we return 0xff to the caller. | ||
*/ | ||
if (WAIT_FOR_BBP(rt2x00dev, ®)) { | ||
reg = 0; | ||
rt2x00_set_field32(®, BBP_CSR_CFG_REGNUM, word); | ||
rt2x00_set_field32(®, BBP_CSR_CFG_BUSY, 1); | ||
rt2x00_set_field32(®, BBP_CSR_CFG_READ_CONTROL, 1); | ||
if (rt2x00_intf_is_pci(rt2x00dev)) | ||
rt2x00_set_field32(®, BBP_CSR_CFG_BBP_RW_MODE, 1); | ||
|
||
rt2800_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg); | ||
|
||
WAIT_FOR_BBP(rt2x00dev, ®); | ||
} | ||
|
||
*value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE); | ||
|
||
mutex_unlock(&rt2x00dev->csr_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(rt2800_bbp_read); | ||
|
||
void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev, | ||
const unsigned int word, const u8 value) | ||
{ | ||
u32 reg; | ||
|
||
mutex_lock(&rt2x00dev->csr_mutex); | ||
|
||
/* | ||
* Wait until the RFCSR becomes available, afterwards we | ||
* can safely write the new data into the register. | ||
*/ | ||
if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { | ||
reg = 0; | ||
rt2x00_set_field32(®, RF_CSR_CFG_DATA, value); | ||
rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); | ||
rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 1); | ||
rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); | ||
|
||
rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); | ||
} | ||
|
||
mutex_unlock(&rt2x00dev->csr_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(rt2800_rfcsr_write); | ||
|
||
void rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, | ||
const unsigned int word, u8 *value) | ||
{ | ||
u32 reg; | ||
|
||
mutex_lock(&rt2x00dev->csr_mutex); | ||
|
||
/* | ||
* Wait until the RFCSR becomes available, afterwards we | ||
* can safely write the read request into the register. | ||
* After the data has been written, we wait until hardware | ||
* returns the correct value, if at any time the register | ||
* doesn't become available in time, reg will be 0xffffffff | ||
* which means we return 0xff to the caller. | ||
*/ | ||
if (WAIT_FOR_RFCSR(rt2x00dev, ®)) { | ||
reg = 0; | ||
rt2x00_set_field32(®, RF_CSR_CFG_REGNUM, word); | ||
rt2x00_set_field32(®, RF_CSR_CFG_WRITE, 0); | ||
rt2x00_set_field32(®, RF_CSR_CFG_BUSY, 1); | ||
|
||
rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG, reg); | ||
|
||
WAIT_FOR_RFCSR(rt2x00dev, ®); | ||
} | ||
|
||
*value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA); | ||
|
||
mutex_unlock(&rt2x00dev->csr_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(rt2800_rfcsr_read); | ||
|
||
void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, | ||
const unsigned int word, const u32 value) | ||
{ | ||
u32 reg; | ||
|
||
mutex_lock(&rt2x00dev->csr_mutex); | ||
|
||
/* | ||
* Wait until the RF becomes available, afterwards we | ||
* can safely write the new data into the register. | ||
*/ | ||
if (WAIT_FOR_RF(rt2x00dev, ®)) { | ||
reg = 0; | ||
rt2x00_set_field32(®, RF_CSR_CFG0_REG_VALUE_BW, value); | ||
rt2x00_set_field32(®, RF_CSR_CFG0_STANDBYMODE, 0); | ||
rt2x00_set_field32(®, RF_CSR_CFG0_SEL, 0); | ||
rt2x00_set_field32(®, RF_CSR_CFG0_BUSY, 1); | ||
|
||
rt2800_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg); | ||
rt2x00_rf_write(rt2x00dev, word, value); | ||
} | ||
|
||
mutex_unlock(&rt2x00dev->csr_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(rt2800_rf_write); | ||
|
||
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | ||
const u8 command, const u8 token, | ||
const u8 arg0, const u8 arg1) | ||
{ | ||
u32 reg; | ||
|
||
if (rt2x00_intf_is_pci(rt2x00dev)) { | ||
/* | ||
* RT2880 and RT3052 don't support MCU requests. | ||
*/ | ||
if (rt2x00_rt(&rt2x00dev->chip, RT2880) || | ||
rt2x00_rt(&rt2x00dev->chip, RT3052)) | ||
return; | ||
} | ||
|
||
mutex_lock(&rt2x00dev->csr_mutex); | ||
|
||
/* | ||
* Wait until the MCU becomes available, afterwards we | ||
* can safely write the new data into the register. | ||
*/ | ||
if (WAIT_FOR_MCU(rt2x00dev, ®)) { | ||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); | ||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | ||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); | ||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); | ||
rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg); | ||
|
||
reg = 0; | ||
rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg); | ||
} | ||
|
||
mutex_unlock(&rt2x00dev->csr_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(rt2800_mcu_request); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.