/* Driver for Realtek PCI-Express card reader
*
* Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* 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, 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, see <http://www.gnu.org/licenses/>.
*
* Author:
* Wei WANG (wei_wang@realsil.com.cn)
* Micky Ching (micky_ching@realsil.com.cn)
*/
#include <linux/blkdev.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/kernel.h>
#include "rtsx.h"
#include "sd.h"
#include "xd.h"
#include "ms.h"
void do_remaining_work(struct rtsx_chip *chip)
{
struct sd_info *sd_card = &(chip->sd_card);
#ifdef XD_DELAY_WRITE
struct xd_info *xd_card = &(chip->xd_card);
#endif
struct ms_info *ms_card = &(chip->ms_card);
if (chip->card_ready & SD_CARD) {
if (sd_card->seq_mode) {
rtsx_set_stat(chip, RTSX_STAT_RUN);
sd_card->cleanup_counter++;
} else {
sd_card->cleanup_counter = 0;
}
}
#ifdef XD_DELAY_WRITE
if (chip->card_ready & XD_CARD) {
if (xd_card->delay_write.delay_write_flag) {
rtsx_set_stat(chip, RTSX_STAT_RUN);
xd_card->cleanup_counter++;
} else {
xd_card->cleanup_counter = 0;
}
}
#endif
if (chip->card_ready & MS_CARD) {
if (CHK_MSPRO(ms_card)) {
if (ms_card->seq_mode) {
rtsx_set_stat(chip, RTSX_STAT_RUN);
ms_card->cleanup_counter++;
} else {
ms_card->cleanup_counter = 0;
}
} else {
#ifdef MS_DELAY_WRITE
if (ms_card->delay_write.delay_write_flag) {
rtsx_set_stat(chip, RTSX_STAT_RUN);
ms_card->cleanup_counter++;
} else {
ms_card->cleanup_counter = 0;
}
#endif
}
}
if (sd_card->cleanup_counter > POLLING_WAIT_CNT)
sd_cleanup_work(chip);
if (xd_card->cleanup_counter > POLLING_WAIT_CNT)
xd_cleanup_work(chip);
if (ms_card->cleanup_counter > POLLING_WAIT_CNT)
ms_cleanup_work(chip);
}
void try_to_switch_sdio_ctrl(struct rtsx_chip *chip)
{
u8 reg1 = 0, reg2 = 0;
rtsx_read_register(chip, 0xFF34, ®1);
rtsx_read_register(chip, 0xFF38, ®2);
dev_dbg(rtsx_dev(chip), "reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n",
reg1, reg2);
if ((reg1 & 0xC0) && (reg2 &