2011-04-05 09:42:12 -07:00
/******************************************************************************
*
2013-01-21 21:39:26 +01:00
* Copyright ( c ) 2003 - 2013 Intel Corporation . All rights reserved .
2011-04-05 09:42:12 -07:00
*
* Portions of this file are derived from the ipw3945 project .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* 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 . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 , USA
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE .
*
* Contact Information :
* Intel Linux Wireless < ilw @ linux . intel . com >
* Intel Corporation , 5200 N . E . Elam Young Parkway , Hillsboro , OR 97124 - 6497
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-08-25 23:11:14 -07:00
# include <linux/delay.h>
# include <linux/device.h>
2012-05-16 22:54:27 +02:00
# include <linux/export.h>
2011-04-05 09:42:12 -07:00
2013-03-01 00:13:33 +01:00
# include "iwl-drv.h"
2011-04-05 09:42:12 -07:00
# include "iwl-io.h"
2012-06-06 14:17:46 +02:00
# include "iwl-csr.h"
2011-08-25 23:11:14 -07:00
# include "iwl-debug.h"
2011-04-05 09:42:12 -07:00
# define IWL_POLL_INTERVAL 10 /* microseconds */
2012-01-03 16:56:15 +02:00
int iwl_poll_bit ( struct iwl_trans * trans , u32 addr ,
2011-04-05 09:42:12 -07:00
u32 bits , u32 mask , int timeout )
{
int t = 0 ;
do {
2012-01-03 16:56:15 +02:00
if ( ( iwl_read32 ( trans , addr ) & mask ) = = ( bits & mask ) )
2011-04-05 09:42:12 -07:00
return t ;
udelay ( IWL_POLL_INTERVAL ) ;
t + = IWL_POLL_INTERVAL ;
} while ( t < timeout ) ;
return - ETIMEDOUT ;
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_poll_bit ) ;
2011-04-05 09:42:12 -07:00
2012-01-03 16:56:15 +02:00
u32 iwl_read_direct32 ( struct iwl_trans * trans , u32 reg )
2011-04-05 09:42:12 -07:00
{
2012-12-31 13:46:42 +02:00
u32 value = 0x5a5a5a5a ;
2011-04-05 09:42:12 -07:00
unsigned long flags ;
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-12-31 13:46:42 +02:00
value = iwl_read32 ( trans , reg ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2012-12-31 13:46:42 +02:00
}
2011-04-05 09:42:12 -07:00
return value ;
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_read_direct32 ) ;
2011-04-05 09:42:12 -07:00
2012-01-03 16:56:15 +02:00
void iwl_write_direct32 ( struct iwl_trans * trans , u32 reg , u32 value )
2011-04-05 09:42:12 -07:00
{
unsigned long flags ;
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-01-03 16:56:15 +02:00
iwl_write32 ( trans , reg , value ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2011-04-05 09:42:12 -07:00
}
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_write_direct32 ) ;
2011-04-05 09:42:12 -07:00
2012-01-03 16:56:15 +02:00
int iwl_poll_direct_bit ( struct iwl_trans * trans , u32 addr , u32 mask ,
2011-04-05 09:42:12 -07:00
int timeout )
{
int t = 0 ;
do {
2012-01-03 16:56:15 +02:00
if ( ( iwl_read_direct32 ( trans , addr ) & mask ) = = mask )
2011-04-05 09:42:12 -07:00
return t ;
udelay ( IWL_POLL_INTERVAL ) ;
t + = IWL_POLL_INTERVAL ;
} while ( t < timeout ) ;
return - ETIMEDOUT ;
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_poll_direct_bit ) ;
2011-04-05 09:42:12 -07:00
2012-12-02 13:07:30 +02:00
static inline u32 __iwl_read_prph ( struct iwl_trans * trans , u32 ofs )
2011-04-05 09:42:12 -07:00
{
2012-12-02 13:07:30 +02:00
u32 val = iwl_trans_read_prph ( trans , ofs ) ;
trace_iwlwifi_dev_ioread_prph32 ( trans - > dev , ofs , val ) ;
return val ;
2011-04-05 09:42:12 -07:00
}
2012-12-02 13:07:30 +02:00
static inline void __iwl_write_prph ( struct iwl_trans * trans , u32 ofs , u32 val )
2011-04-05 09:42:12 -07:00
{
2012-12-02 13:07:30 +02:00
trace_iwlwifi_dev_iowrite_prph32 ( trans - > dev , ofs , val ) ;
iwl_trans_write_prph ( trans , ofs , val ) ;
2011-04-05 09:42:12 -07:00
}
2012-12-02 13:07:30 +02:00
u32 iwl_read_prph ( struct iwl_trans * trans , u32 ofs )
2011-04-05 09:42:12 -07:00
{
unsigned long flags ;
2012-12-31 13:46:42 +02:00
u32 val = 0x5a5a5a5a ;
2011-04-05 09:42:12 -07:00
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-12-31 13:46:42 +02:00
val = __iwl_read_prph ( trans , ofs ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2012-12-31 13:46:42 +02:00
}
2011-04-05 09:42:12 -07:00
return val ;
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_read_prph ) ;
2011-04-05 09:42:12 -07:00
2012-12-02 13:07:30 +02:00
void iwl_write_prph ( struct iwl_trans * trans , u32 ofs , u32 val )
2011-04-05 09:42:12 -07:00
{
unsigned long flags ;
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-12-02 13:07:30 +02:00
__iwl_write_prph ( trans , ofs , val ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2011-04-05 09:42:12 -07:00
}
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_write_prph ) ;
2011-04-05 09:42:12 -07:00
2012-12-02 13:07:30 +02:00
void iwl_set_bits_prph ( struct iwl_trans * trans , u32 ofs , u32 mask )
2011-04-05 09:42:12 -07:00
{
unsigned long flags ;
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-12-02 13:07:30 +02:00
__iwl_write_prph ( trans , ofs ,
__iwl_read_prph ( trans , ofs ) | mask ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2012-03-07 09:52:24 -08:00
}
2011-04-05 09:42:12 -07:00
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_set_bits_prph ) ;
2011-04-05 09:42:12 -07:00
2012-12-02 13:07:30 +02:00
void iwl_set_bits_mask_prph ( struct iwl_trans * trans , u32 ofs ,
2011-04-05 09:42:12 -07:00
u32 bits , u32 mask )
{
unsigned long flags ;
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-12-02 13:07:30 +02:00
__iwl_write_prph ( trans , ofs ,
( __iwl_read_prph ( trans , ofs ) & mask ) | bits ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2012-03-07 09:52:24 -08:00
}
2011-04-05 09:42:12 -07:00
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_set_bits_mask_prph ) ;
2011-04-05 09:42:12 -07:00
2012-12-02 13:07:30 +02:00
void iwl_clear_bits_prph ( struct iwl_trans * trans , u32 ofs , u32 mask )
2011-04-05 09:42:12 -07:00
{
unsigned long flags ;
u32 val ;
2013-01-16 11:34:49 +02:00
if ( iwl_trans_grab_nic_access ( trans , false , & flags ) ) {
2012-12-02 13:07:30 +02:00
val = __iwl_read_prph ( trans , ofs ) ;
__iwl_write_prph ( trans , ofs , ( val & ~ mask ) ) ;
2013-01-16 11:34:49 +02:00
iwl_trans_release_nic_access ( trans , & flags ) ;
2012-03-07 09:52:24 -08:00
}
2011-04-05 09:42:12 -07:00
}
2013-03-01 00:13:33 +01:00
IWL_EXPORT_SYMBOL ( iwl_clear_bits_prph ) ;