/*
* linux/drivers/media/mmc/omap.c
*
* Copyright (C) 2004 Nokia Corporation
* Written by Tuukka Tikkanen and Juha Yrj�l�<juha.yrjola@nokia.com>
* Misc hacks here and there by Tony Lindgren <tony@atomide.com>
* Other hacks (DMA, SD, etc) by David Brownell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/mmc/host.h>
#include <linux/mmc/protocol.h>
#include <linux/mmc/card.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/scatterlist.h>
#include <asm/mach-types.h>
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/dma.h>
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
#include <asm/arch/tps65010.h>
#include "omap.h"
#define DRIVER_NAME "mmci-omap"
#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
/* Specifies how often in millisecs to poll for card status changes
* when the cover switch is open */
#define OMAP_MMC_SWITCH_POLL_DELAY 500
static int mmc_omap_enable_poll = 1;
struct mmc_omap_host {
int initialized;
int suspended;
struct mmc_request * mrq;
struct mmc_command * cmd;
struct mmc_data * data;
struct mmc_host * mmc;
struct device * dev;
unsigned char id; /* 16xx chips have 2 MMC blocks */
struct clk * iclk;
struct clk * fclk;
struct resource *res;
void __iomem *base;
int irq;
unsigned char bus_mode;
unsigned char hw_bus_mode;
unsigned int sg_len;
int sg_idx;
u16 * buffer;
u32 buffer_bytes_left;
u32 total_bytes_left;
unsigned use_dma:1;
unsigned brs_received:1, dma_done:1;
unsigned dma_is_read:1;
unsigned dma_in_use:1;
int dma_ch;
spinlock_t dma_lock;
struct timer_list dma_timer;
unsigned dma_len;
short power_pin;
short wp_pin;
int switch_pin;
struct work_struct switch_work;
struct timer_list switch_timer;
int switch_last_state;
};
static inline int
mmc_omap_cover_is_open(struct mmc_omap_host *host)
{
if (host->switch_pin < 0)
return 0;
return omap_get_gpio_datain(host->switch_pin);
}
static ssize_t
mmc_omap_show_cover_switch(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct mmc_omap_host *host = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", mmc_omap_cover_is_open(host) ? "open" :
"closed");
}
static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
static ssize_t
mmc_omap_show_enable_poll(struct device *dev,
struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", mmc_omap_enable_poll<