|
|
|
|
@@ -52,6 +52,7 @@
|
|
|
|
|
#include <asm/arch/regs-gpio.h>
|
|
|
|
|
#include <asm/arch/regs-clock.h>
|
|
|
|
|
#include <asm/arch/regs-spi.h>
|
|
|
|
|
#include <asm/arch/regs-irq.h>
|
|
|
|
|
#include <asm/dma.h>
|
|
|
|
|
|
|
|
|
|
#include "spi-dev.h"
|
|
|
|
|
@@ -60,7 +61,7 @@
|
|
|
|
|
#define CONFIG_AUTO_nSS 0
|
|
|
|
|
#define CONFIG_DO_SWRST 1
|
|
|
|
|
#define CONFIG_USE_PKTCNT 1
|
|
|
|
|
#define CONFIG_SPI_PRESCALER 1
|
|
|
|
|
#define CONFIG_SPI_PRESCALER 1
|
|
|
|
|
|
|
|
|
|
#define CONFIG_TX_LVL 0x20
|
|
|
|
|
#define CONFIG_RX_LVL 0x10
|
|
|
|
|
@@ -86,7 +87,132 @@ static void s3c_spi_wifi_if_on(void);
|
|
|
|
|
static void s3c_spi_wifi_if_off(void);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#undef debug
|
|
|
|
|
//blacksu add
|
|
|
|
|
#define S3C2416_GPKCON S3C2410_GPIOREG(0xe0)
|
|
|
|
|
#define S3C2416_GPKDAT S3C2410_GPIOREG(0xe4)
|
|
|
|
|
#define S3C2416_GPKUDP S3C2410_GPIOREG(0xe8)
|
|
|
|
|
|
|
|
|
|
irqreturn_t Wlan_irq (int i4Irq, void *pvDevID)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printk("Wlan_irq()++\n");
|
|
|
|
|
|
|
|
|
|
disable_irq(IRQ_EINT3);
|
|
|
|
|
enable_irq(IRQ_EINT3);
|
|
|
|
|
|
|
|
|
|
printk("Wlan_irq()--\n");
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
myhexdump(char *pfx, unsigned char *msg, int msglen)
|
|
|
|
|
{
|
|
|
|
|
int i, col;
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
col = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < msglen; i++, col++) {
|
|
|
|
|
if (col % 16 == 0)
|
|
|
|
|
strcpy(buf, pfx);
|
|
|
|
|
sprintf(buf + strlen(buf), "%02x", msg[i]);
|
|
|
|
|
if ((col + 1) % 16 == 0)
|
|
|
|
|
printk("%s\n", buf);
|
|
|
|
|
else
|
|
|
|
|
sprintf(buf + strlen(buf), " ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (col % 16 != 0)
|
|
|
|
|
printk("%s\n", buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClearSourcePenging(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
writel( (1<<3), S3C2410_SRCPND);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClearIntrPenging(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
writel( (1<<3), S3C2410_INTPND);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S3cEnableIntr(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// writel(readl(S3C2410_INTMSK)& ~(1<<3), S3C2410_INTMSK);
|
|
|
|
|
writel(readl(S3C2410_INTMSK)& 0xfffffff7, S3C2410_INTMSK);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void S3cDisableIntr(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
writel(readl(S3C2410_INTMSK)|(1<<3), S3C2410_INTMSK);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
struct spi_dev *prSpiDev;
|
|
|
|
|
int ret;
|
|
|
|
|
unsigned char Write;
|
|
|
|
|
// int i;
|
|
|
|
|
|
|
|
|
|
//myhexdump("OUT:", msg_out,msglen);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
if( (sd->wordlen!=2) || (sd->resp_delay_all) )
|
|
|
|
|
{
|
|
|
|
|
printk("********************************\n");
|
|
|
|
|
printk("******* BlackSu *****************\n");
|
|
|
|
|
printk("********Watch Here***************\n");
|
|
|
|
|
printk("wordlen=%d, resp_delay_all=%d\n",sd->wordlen,sd->resp_delay_all);
|
|
|
|
|
printk("********************************\n");
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
Write=msg_out[2] & 0x80;//bit 7: read:0, write :1
|
|
|
|
|
prSpiDev = spi_dev_get_by_minor(0);
|
|
|
|
|
if(Write)
|
|
|
|
|
{
|
|
|
|
|
ret = spi_master_send(prSpiDev, (char *)&msg_out[0], msglen-4);//send CMD
|
|
|
|
|
ret = spi_master_recv(prSpiDev, (char *)&msg_in[msglen-4], 4);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret = spi_master_send(prSpiDev, (char *)&msg_out[0], 4);//send CMD
|
|
|
|
|
ret = spi_master_recv(prSpiDev, (char *)&msg_in[4], msglen-4);
|
|
|
|
|
}
|
|
|
|
|
//myhexdump("I N:", msg_in,msglen);
|
|
|
|
|
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(ClearSourcePenging);
|
|
|
|
|
EXPORT_SYMBOL(ClearIntrPenging);
|
|
|
|
|
EXPORT_SYMBOL(S3cEnableIntr);
|
|
|
|
|
EXPORT_SYMBOL(S3cDisableIntr);
|
|
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(spi_sendrecv);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef debug
|
|
|
|
|
//#define debug
|
|
|
|
|
#ifdef debug
|
|
|
|
|
#define DBG(x...) printk(x)
|
|
|
|
|
@@ -112,7 +238,7 @@ void print_reg(struct s3c_spi *spi) { }
|
|
|
|
|
|
|
|
|
|
static void s3c_spi_free(struct s3c_spi *spi)
|
|
|
|
|
{
|
|
|
|
|
//DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
if (spi->clk != NULL && !IS_ERR(spi->clk)) {
|
|
|
|
|
clk_disable(spi->clk);
|
|
|
|
|
@@ -139,7 +265,7 @@ static void s3c_spi_free(struct s3c_spi *spi)
|
|
|
|
|
|
|
|
|
|
static void s3c_spi_wifi_if_on()
|
|
|
|
|
{
|
|
|
|
|
printk("\n[HIKO HSPI] s3c_spi_wifi_if_on()\n");
|
|
|
|
|
printk("s3c_spi_wifi_if_on()++\n");
|
|
|
|
|
|
|
|
|
|
/* program defaults into the registers */
|
|
|
|
|
writel(readl(S3C2443_SCLKCON)|(1<<14), S3C2443_SCLKCON);
|
|
|
|
|
@@ -168,30 +294,82 @@ static void s3c_spi_wifi_if_on()
|
|
|
|
|
/* GeorgeKuo: */
|
|
|
|
|
//s3c2410_gpio_pullup(S3C2410_GPL13, 2); /* pull-up enable */
|
|
|
|
|
|
|
|
|
|
//GPK5, PA 3.3V
|
|
|
|
|
//writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
|
|
|
|
|
//writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
|
|
|
|
|
//writel(((readl(S3C2416_GPKUDP) & (1<<11)) | ~(1<<10)), S3C2416_GPKUDP);
|
|
|
|
|
|
|
|
|
|
//GPK6, PA 1.8V
|
|
|
|
|
//writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
|
|
|
|
|
//writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
|
|
|
|
|
//writel(((readl(S3C2416_GPKUDP) & (1<<13)) | ~(1<<12)), S3C2416_GPKUDP);
|
|
|
|
|
/*
|
|
|
|
|
printk("GPK_CON = 0x%08x\n",readl(S3C2416_GPKCON));
|
|
|
|
|
|
|
|
|
|
writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
|
|
|
|
|
writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
|
|
|
|
|
writel(((readl(S3C2416_GPKUDP) & (1<<13)) | ~(1<<12)), S3C2416_GPKUDP);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//GPK5, WIFI 3.3V
|
|
|
|
|
printk("GPK_CON = 0x%08x\n",readl(S3C2416_GPKCON));
|
|
|
|
|
|
|
|
|
|
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
|
|
|
|
|
writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
|
|
|
|
|
writel(((readl(S3C2416_GPKUDP) & (1<<11)) | ~(1<<10)), S3C2416_GPKUDP);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//GPK7, PA 3.3V
|
|
|
|
|
printk("GPK_CON = 0x%08x\n",readl(S3C2416_GPKCON));
|
|
|
|
|
|
|
|
|
|
writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
|
|
|
|
|
writel((readl(S3C2416_GPKDAT) | (1<<7)), S3C2416_GPKDAT);
|
|
|
|
|
writel(((readl(S3C2416_GPKUDP) & (1<<15)) | ~(1<<14)), S3C2416_GPKUDP);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
//WIFI_BT_EN
|
|
|
|
|
//GPG4
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_OUTP);
|
|
|
|
|
// s3c2410_gpio_setpin(S3C2410_GPG4, 0);
|
|
|
|
|
// mdelay(1);
|
|
|
|
|
s3c2410_gpio_setpin(S3C2410_GPG4, 1);
|
|
|
|
|
mdelay(20);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* GeorgeKuo: */
|
|
|
|
|
//EXT Reset
|
|
|
|
|
//s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
|
|
|
|
|
//s3c2410_gpio_setpin(S3C2410_GPD8, 0);
|
|
|
|
|
//mdelay(1);
|
|
|
|
|
//s3c2410_gpio_setpin(S3C2410_GPD8, 1);
|
|
|
|
|
//mdelay(20);
|
|
|
|
|
//EXT_N_WIFI_RST
|
|
|
|
|
//GPD8
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
|
|
|
|
|
s3c2410_gpio_setpin(S3C2410_GPD8, 0);
|
|
|
|
|
mdelay(1);
|
|
|
|
|
s3c2410_gpio_setpin(S3C2410_GPD8, 1);
|
|
|
|
|
mdelay(20);
|
|
|
|
|
printk("s3c_spi_wifi_if_on()--\n");
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL_GPL(s3c_spi_wifi_if_on);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void s3c_spi_wifi_if_off()
|
|
|
|
|
{
|
|
|
|
|
printk("\n[HIKO HSPI] s3c_spi_wifi_if_off()\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//GPK7, PA 3.3V
|
|
|
|
|
printk("+GPK_DAT = 0x%08x\n",readl(S3C2416_GPKDAT));
|
|
|
|
|
writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
|
|
|
|
|
writel(((readl(S3C2416_GPKUDP) & ~(1<<15)) | (1<<14)), S3C2416_GPKUDP);
|
|
|
|
|
writel((readl(S3C2416_GPKDAT) & ~(1<<7)), S3C2416_GPKDAT);
|
|
|
|
|
// writel(((readl(S3C2416_GPKUDP) & (1<<15)) | ~(1<<14)), S3C2416_GPKUDP);
|
|
|
|
|
printk("-GPK_DAT = 0x%08x\n",readl(S3C2416_GPKDAT));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//GPK5, WIFI 3.3V
|
|
|
|
|
printk("+GPK_DAT = 0x%08x\n",readl(S3C2416_GPKDAT));
|
|
|
|
|
|
|
|
|
|
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
|
|
|
|
|
writel(((readl(S3C2416_GPKUDP) & ~(1<<11)) | (1<<10)), S3C2416_GPKUDP);
|
|
|
|
|
writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
|
|
|
|
|
// writel(((readl(S3C2416_GPKUDP) & (1<<11)) | ~(1<<10)), S3C2416_GPKUDP);
|
|
|
|
|
printk("-GPK_DAT = 0x%08x\n",readl(S3C2416_GPKDAT));
|
|
|
|
|
printk("s3c_spi_wifi_if_off()\n");
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL_GPL(s3c_spi_wifi_if_off);
|
|
|
|
|
|
|
|
|
|
@@ -236,12 +414,14 @@ static int s3c_spi_hw_init(struct s3c_spi *spi)
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SPICLK_PCLK
|
|
|
|
|
/*Enable PCLK into the HS SPI*/
|
|
|
|
|
printk("Enable PCLK into the HS SPI\n");
|
|
|
|
|
writel(readl(S3C2443_PCLKCON)|(1<<6), S3C2443_PCLKCON);
|
|
|
|
|
|
|
|
|
|
clk_enable(spi->clk);
|
|
|
|
|
|
|
|
|
|
#elif defined CONFIG_SPICLK_EPLL
|
|
|
|
|
/* implemetation when use EPLL clock */
|
|
|
|
|
printk("implemetation when use EPLL clock\n");
|
|
|
|
|
writel(0x800, S3C2443_LOCKCON1);
|
|
|
|
|
writel( (readl( S3C2443_CLKSRC ) | (1 << 6) ), S3C2443_CLKSRC); // EPLL Output
|
|
|
|
|
|
|
|
|
|
@@ -277,7 +457,7 @@ static int s3c_spi_hw_init(struct s3c_spi *spi)
|
|
|
|
|
|
|
|
|
|
static int s3c_spi_dma_init(struct s3c_spi *spi, int mode)
|
|
|
|
|
{
|
|
|
|
|
// DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
// TX
|
|
|
|
|
if (mode == 0) {
|
|
|
|
|
@@ -304,7 +484,7 @@ static int s3c_spi_dma_init(struct s3c_spi *spi, int mode)
|
|
|
|
|
static inline void s3c_spi_write_fifo(struct s3c_spi *spi)
|
|
|
|
|
{
|
|
|
|
|
u32 wdata = 0;
|
|
|
|
|
|
|
|
|
|
DEBUG;
|
|
|
|
|
if (spi->msg->wbuf) {
|
|
|
|
|
wdata = spi->msg->wbuf[spi->msg_ptr++];
|
|
|
|
|
} else {
|
|
|
|
|
@@ -323,7 +503,7 @@ static inline void s3c_spi_write_fifo(struct s3c_spi *spi)
|
|
|
|
|
*/
|
|
|
|
|
static inline void s3c_spi_master_complete(struct s3c_spi *spi, int ret)
|
|
|
|
|
{
|
|
|
|
|
// DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
spi->msg_ptr = 0;
|
|
|
|
|
spi->msg_rd_ptr = 0;
|
|
|
|
|
@@ -358,7 +538,7 @@ static inline void s3c_spi_stop(struct s3c_spi *spi, int ret)
|
|
|
|
|
{
|
|
|
|
|
u32 spi_slavecfg;
|
|
|
|
|
u32 spi_chcfg;
|
|
|
|
|
|
|
|
|
|
DEBUG;
|
|
|
|
|
#if CONFIG_AUTO_nSS
|
|
|
|
|
#else
|
|
|
|
|
/* GeorgeKuo: set nSS high to stop bus operation */
|
|
|
|
|
@@ -396,7 +576,7 @@ void s3c_spi_dma_cb(struct s3c2410_dma_chan *dma_ch, void *buf_id,
|
|
|
|
|
{
|
|
|
|
|
struct s3c_spi *spi = (struct s3c_spi *)buf_id;
|
|
|
|
|
unsigned long status = 0;
|
|
|
|
|
// DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
status = readl(spi->regs + S3C_SPI_STATUS);
|
|
|
|
|
|
|
|
|
|
@@ -427,7 +607,7 @@ static void s3c_spi_message_start(struct s3c_spi *spi)
|
|
|
|
|
//u32 spi_clkcfg = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
#if CONFIG_DO_SWRST /* GeorgeKuo: do software reset */
|
|
|
|
|
writel(readl(spi->regs + S3C_CH_CFG) | SPI_CH_SW_RST, spi->regs + S3C_CH_CFG);
|
|
|
|
|
@@ -615,11 +795,13 @@ static void s3c_spi_message_start(struct s3c_spi *spi)
|
|
|
|
|
|
|
|
|
|
static inline int tx_msgend(struct s3c_spi *spi)
|
|
|
|
|
{
|
|
|
|
|
DEBUG;
|
|
|
|
|
return spi->msg_ptr >= spi->msg->len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int rx_msgend(struct s3c_spi *spi)
|
|
|
|
|
{
|
|
|
|
|
DEBUG;
|
|
|
|
|
return spi->msg_rd_ptr >= spi->msg->len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -733,7 +915,8 @@ static irqreturn_t s3c_spi_irq(int irqno, void *dev_id)
|
|
|
|
|
{
|
|
|
|
|
struct s3c_spi *spi = dev_id;
|
|
|
|
|
unsigned long spi_sts;
|
|
|
|
|
|
|
|
|
|
//printk("[S3C2416]s3c_spi_irq()++\n");
|
|
|
|
|
DEBUG;
|
|
|
|
|
spi_sts = readl(spi->regs + S3C_SPI_STATUS);
|
|
|
|
|
|
|
|
|
|
if (spi_sts & SPI_STUS_RX_OVERRUN_ERR) {
|
|
|
|
|
@@ -762,7 +945,7 @@ static irqreturn_t s3c_spi_irq(int irqno, void *dev_id)
|
|
|
|
|
static int s3c_spi_doxfer(struct s3c_spi *spi, struct spi_msg msgs[], int num)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
DEBUG;
|
|
|
|
|
/* GeorgeKuo: spi_dev->bus_lock is acquired by caller, do we have to do
|
|
|
|
|
* protection again?
|
|
|
|
|
*/
|
|
|
|
|
@@ -783,22 +966,24 @@ static int s3c_spi_doxfer(struct s3c_spi *spi, struct spi_msg msgs[], int num)
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
if (spi->msg->wbuf) {
|
|
|
|
|
// DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
spi->state = STATE_XFER_TX;
|
|
|
|
|
|
|
|
|
|
/* vivek, 2009-04-15 17:40 Notes: write dmabufw to dmabuf_addr */
|
|
|
|
|
if (spi->msg->flags & SPI_M_DMA_MODE) {
|
|
|
|
|
spi->dmabuf_addr = spi->spidev.dmabufw;
|
|
|
|
|
pr_debug("spi->dmabuf_addr = 0x%x\n",spi->dmabuf_addr);
|
|
|
|
|
printk("[W]spi->dmabuf_addr = 0x%x\n",spi->dmabuf_addr);
|
|
|
|
|
}
|
|
|
|
|
} else if (spi->msg->rbuf) {
|
|
|
|
|
// DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
spi->state = STATE_XFER_RX;
|
|
|
|
|
|
|
|
|
|
/* vivek, 2009-04-15 17:41 Notes: write dmabufr to dmabuf_addr */
|
|
|
|
|
if (spi->msg->flags & SPI_M_DMA_MODE) {
|
|
|
|
|
spi->dmabuf_addr = spi->spidev.dmabufr;
|
|
|
|
|
pr_debug("spi->dmabuf_addr = 0x%x\n",spi->dmabuf_addr);
|
|
|
|
|
printk("[R]spi->dmabuf_addr = 0x%x\n",spi->dmabuf_addr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
dev_err(spi->dev,"Unknown functionality \n");
|
|
|
|
|
@@ -844,7 +1029,7 @@ static int s3c_spi_xfer(struct spi_dev *spi_dev,
|
|
|
|
|
struct s3c_spi *spi = (struct s3c_spi *)spi_dev->algo_data;
|
|
|
|
|
int retry;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
DEBUG;
|
|
|
|
|
for (retry = 0; retry < spi_dev->retries; retry++) {
|
|
|
|
|
|
|
|
|
|
ret = s3c_spi_doxfer(spi, msgs, num);
|
|
|
|
|
@@ -865,7 +1050,7 @@ static int s3c_spi_close(struct spi_dev *spi_dev)
|
|
|
|
|
{
|
|
|
|
|
struct s3c_spi *spi = (struct s3c_spi *)spi_dev->algo_data;
|
|
|
|
|
u32 spi_clkcfg;
|
|
|
|
|
//DEBUG;
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
spi_clkcfg = readl( spi->regs + S3C_CLK_CFG);
|
|
|
|
|
/* GeorgeKuo: */
|
|
|
|
|
@@ -959,8 +1144,10 @@ static int s3c_spi_probe(struct platform_device *pdev)
|
|
|
|
|
struct s3c_spi *spi = &s3c_spi[pdev->id];
|
|
|
|
|
struct resource *res;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
DEBUG;
|
|
|
|
|
/* find the clock and enable it */
|
|
|
|
|
printk("s3c_spi_probe(name=%s , id=%d, # resources=%d)++\n", pdev->name, pdev->id,pdev->num_resources);
|
|
|
|
|
|
|
|
|
|
sema_init(&spi->sem, 0);
|
|
|
|
|
spi->nr = pdev->id;
|
|
|
|
|
spi->dev = &pdev->dev;
|
|
|
|
|
@@ -990,7 +1177,7 @@ static int s3c_spi_probe(struct platform_device *pdev)
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printk(KERN_ALERT "resource start : %x\n",res->start);
|
|
|
|
|
printk("resource start : %x\n",res->start);
|
|
|
|
|
|
|
|
|
|
spi->regs = ioremap(res->start, (res->end - res->start) + 1);
|
|
|
|
|
|
|
|
|
|
@@ -1000,7 +1187,7 @@ static int s3c_spi_probe(struct platform_device *pdev)
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printk(KERN_ALERT "hspi registers %p (%p, %p)\n", spi->regs, spi->ioarea, res);
|
|
|
|
|
printk("hspi registers %p (%p, %p)\n", spi->regs, spi->ioarea, res);
|
|
|
|
|
|
|
|
|
|
/* setup info block for the spi core */
|
|
|
|
|
|
|
|
|
|
@@ -1028,6 +1215,8 @@ static int s3c_spi_probe(struct platform_device *pdev)
|
|
|
|
|
|
|
|
|
|
/* GeorgeKuo: */
|
|
|
|
|
//ret = request_irq(res->start, s3c_spi_irq, SA_INTERRUPT, pdev->name, spi);
|
|
|
|
|
printk("[s3c2416]request_irq=%d\n",spi->irq->start);
|
|
|
|
|
|
|
|
|
|
ret = request_irq(spi->irq->start, s3c_spi_irq, SA_INTERRUPT, pdev->name,
|
|
|
|
|
spi);
|
|
|
|
|
|
|
|
|
|
@@ -1039,7 +1228,15 @@ static int s3c_spi_probe(struct platform_device *pdev)
|
|
|
|
|
/* GeorgeKuo: Do initialization here instead of each read/write operation */
|
|
|
|
|
do {
|
|
|
|
|
/* MT5921 uses CPOL=1, CPHA=1 */
|
|
|
|
|
u32 spi_chcfg = SPI_CH_MASTER | SPI_CH_FALLING | SPI_CH_FORMAT_B;
|
|
|
|
|
// u32 spi_chcfg = SPI_CH_MASTER | SPI_CH_FALLING | SPI_CH_FORMAT_B;
|
|
|
|
|
|
|
|
|
|
//blacksu mod
|
|
|
|
|
u32 spi_chcfg = SPI_CH_MASTER | SPI_CH_RISING | SPI_CH_FORMAT_A;
|
|
|
|
|
// spi_chcfg = SPI_CH_MASTER | SPI_CH_RISING | SPI_CH_FORMAT_B;
|
|
|
|
|
// spi_chcfg = SPI_CH_MASTER | SPI_CH_FALLING | SPI_CH_FORMAT_A;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//u32 spi_clkcfg = SPI_ENCLK_ENABLE | 1; /* prescaler = 1 */
|
|
|
|
|
u32 spi_clkcfg = SPI_ENCLK_ENABLE | CONFIG_SPI_PRESCALER; /* prescaler = 1 */
|
|
|
|
|
//0:44.435 Mhz, 1:22.2175 Mhz, 2:14.81 Mhz, 3:11.10875 Mhz, 4:8.887Mhz
|
|
|
|
|
@@ -1106,6 +1303,95 @@ static int s3c_spi_probe(struct platform_device *pdev)
|
|
|
|
|
s3c_spi_dma_init(spi, 1);
|
|
|
|
|
printk("spi read channel is %d\n",spi->dmar);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
printk("GPFCON=%08X\n",readl(S3C2410_GPFCON));
|
|
|
|
|
printk("GPFDAT=%08X\n",readl(S3C2410_GPFDAT));
|
|
|
|
|
printk("GPFUP=%08X\n",readl(S3C2410_GPFUP));
|
|
|
|
|
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_OUTP);
|
|
|
|
|
//s3c2410_gpio_pullup(S3C2410_GPF3, 0); // pull-up/down disable
|
|
|
|
|
s3c2410_gpio_pullup(S3C2410_GPF3, 1); // pull-down enable
|
|
|
|
|
|
|
|
|
|
writel( (readl( S3C2410_GPFDAT ) | (1 << 3) ), S3C2410_GPFDAT); // EPLL Output
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
|
|
printk("GPFCON=%08X\n",readl(S3C2410_GPFCON));
|
|
|
|
|
printk("GPFDAT=%08X\n",readl(S3C2410_GPFDAT));
|
|
|
|
|
printk("GPFUP=%08X\n",readl(S3C2410_GPFUP));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_INP);
|
|
|
|
|
//s3c2410_gpio_pullup(S3C2410_GPF3, 0); /* pull-up/down disable */
|
|
|
|
|
s3c2410_gpio_pullup(S3C2410_GPF3, 1); /* pull-down enable */
|
|
|
|
|
// s3c2410_gpio_pullup(S3C2410_GPF3, 2); /* pull-up enable */
|
|
|
|
|
//set_irq_type(WLAN_STA_IRQ, IRQ_TYPE_LEVEL_LOW);
|
|
|
|
|
set_irq_type(IRQ_EINT3, IRQ_TYPE_LEVEL_HIGH);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printk("GPFCON=%08X\n",readl(S3C2410_GPFCON));
|
|
|
|
|
printk("GPFDAT=%08X\n",readl(S3C2410_GPFDAT));
|
|
|
|
|
printk("GPFUP=%08X\n",readl(S3C2410_GPFUP));
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3);
|
|
|
|
|
//s3c2410_gpio_pullup(S3C2410_GPF3, 0); // pull-up/down disable
|
|
|
|
|
s3c2410_gpio_pullup(S3C2410_GPF3, 1); // pull-down enable
|
|
|
|
|
// s3c2410_gpio_pullup(S3C2410_GPF3, 2); // pull-up enable
|
|
|
|
|
// set_irq_type(IRQ_EINT3, IRQ_TYPE_LEVEL_LOW);
|
|
|
|
|
set_irq_type(IRQ_EINT3, IRQ_TYPE_LEVEL_HIGH);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3);
|
|
|
|
|
//s3c2410_gpio_pullup(S3C2410_GPF3, 0); // pull-up/down disable
|
|
|
|
|
s3c2410_gpio_pullup(S3C2410_GPF3, 2); // pull-up enable
|
|
|
|
|
//set_irq_type(WLAN_STA_IRQ, IRQ_TYPE_LEVEL_LOW);
|
|
|
|
|
// set_irq_type(IRQ_EINT3, IRQ_TYPE_EDGE_FALLING);
|
|
|
|
|
set_irq_type(IRQ_EINT3, IRQ_TYPE_EDGE_FALLING);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mdelay(100);
|
|
|
|
|
|
|
|
|
|
// ret = request_irq(IRQ_EINT3, Wlan_irq, IRQ_TYPE_EDGE_FALLING | IRQ_DISABLED, "EINT3-test", NULL);
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printk("GPFCON=%08X\n",readl(S3C2410_GPFCON));
|
|
|
|
|
printk("GPFDAT=%08X\n",readl(S3C2410_GPFDAT));
|
|
|
|
|
printk("GPFUP=%08X\n",readl(S3C2410_GPFUP));
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
s3c_spi_free(spi);
|
|
|
|
|
@@ -1166,6 +1452,91 @@ out:
|
|
|
|
|
|
|
|
|
|
} while (0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 1 /* BCM4329 read test*/
|
|
|
|
|
do {
|
|
|
|
|
|
|
|
|
|
struct spi_dev *prSpiDev;
|
|
|
|
|
int ret;
|
|
|
|
|
// int i;
|
|
|
|
|
sdioh_info_t sd;
|
|
|
|
|
|
|
|
|
|
unsigned C[4];
|
|
|
|
|
unsigned char buf[128]={0x0,};
|
|
|
|
|
unsigned char msg_out[128]={0xa0,0x04,0x00,0x00,};
|
|
|
|
|
unsigned char msg_in[128]={0,};
|
|
|
|
|
int msglen=16;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CMD_READ 0
|
|
|
|
|
#define CMD_WRITE 1
|
|
|
|
|
#define ACCESS_FIXED 0
|
|
|
|
|
#define ACCESS_INCREMENTAL 1
|
|
|
|
|
#define FUN_0 0
|
|
|
|
|
#define FUN_1 1
|
|
|
|
|
#define FUN_2 2
|
|
|
|
|
#define FUN_3 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int SPI_Cmd=CMD_READ;
|
|
|
|
|
unsigned int SPI_Acc=ACCESS_INCREMENTAL;
|
|
|
|
|
unsigned int SPI_Fun=FUN_0;
|
|
|
|
|
unsigned int SPI_Add=0x14;
|
|
|
|
|
unsigned int SPI_Len=0x4;
|
|
|
|
|
unsigned int CMD=0x0;
|
|
|
|
|
|
|
|
|
|
CMD= (SPI_Cmd <<31) | (SPI_Acc<<30) | (SPI_Fun<<28) | (SPI_Add<<11) | (SPI_Len<<0);
|
|
|
|
|
|
|
|
|
|
C[3]=(CMD & 0xff000000) >> 24;
|
|
|
|
|
C[2]=(CMD & 0x00ff0000) >> 16;
|
|
|
|
|
C[1]=(CMD & 0x0000ff00) >> 8;
|
|
|
|
|
C[0]=(CMD & 0x000000ff) >>0;
|
|
|
|
|
|
|
|
|
|
buf[0]=C[1];
|
|
|
|
|
buf[1]=C[0];
|
|
|
|
|
buf[2]=C[3];
|
|
|
|
|
buf[3]=C[2];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// GeorgeKuo:
|
|
|
|
|
s3c2410_gpio_setpin(S3C2410_GPD8, 0);
|
|
|
|
|
mdelay(1);
|
|
|
|
|
s3c2410_gpio_setpin(S3C2410_GPD8, 1);
|
|
|
|
|
mdelay(20);
|
|
|
|
|
*/
|
|
|
|
|
prSpiDev = spi_dev_get_by_minor(0);
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
|
// for (i = 0; i < 10; i++) {
|
|
|
|
|
ret = spi_master_send(prSpiDev, (char *)&buf[0], 4);
|
|
|
|
|
ret = spi_master_recv(prSpiDev, (char *)&buf[4], 8);
|
|
|
|
|
printk("****BCM4329 read test****\n");
|
|
|
|
|
if( (buf[4]==0xBE) &&
|
|
|
|
|
(buf[5]==0xAD) &&
|
|
|
|
|
(buf[6]==0xFE) &&
|
|
|
|
|
(buf[7]==0xED) )
|
|
|
|
|
printk("$$$$$$$ Success to read Reg. 0x14 buf1=%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
|
|
|
|
|
else
|
|
|
|
|
printk("!!!!!! Failed to read Reg. 0x14\n");
|
|
|
|
|
// }
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sd.wordlen=2;
|
|
|
|
|
sd.resp_delay_all=0;
|
|
|
|
|
spi_sendrecv(&sd,msg_out, msg_in, msglen);
|
|
|
|
|
myhexdump("OUT:", msg_out,msglen);
|
|
|
|
|
myhexdump("I N:", msg_in,msglen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//ret = spi_master_recv(prSpiDev, (char *)&u4RVal, sizeof(u32));
|
|
|
|
|
//printk(KERN_INFO "read 0x%x\n", u4RVal);
|
|
|
|
|
} while (0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 0 /* MT5921 Initial */
|
|
|
|
|
do {
|
|
|
|
|
u32 u4InitCmd = 0x00040000UL;
|
|
|
|
|
@@ -1223,7 +1594,7 @@ out:
|
|
|
|
|
}
|
|
|
|
|
} while (0);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
printk("s3c_spi_probe()--\n");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1258,6 +1629,7 @@ static int s3c_spi_remove(struct platform_device *pdev)
|
|
|
|
|
static int s3c_spi_suspend(struct platform_device *pdev, pm_message_t msg)
|
|
|
|
|
{
|
|
|
|
|
struct s3c_spi *hw = platform_get_drvdata(pdev);
|
|
|
|
|
DEBUG;
|
|
|
|
|
clk_disable(hw->clk);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -1265,6 +1637,7 @@ static int s3c_spi_suspend(struct platform_device *pdev, pm_message_t msg)
|
|
|
|
|
static int s3c_spi_resume(struct platform_device *pdev)
|
|
|
|
|
{
|
|
|
|
|
struct s3c_spi *hw = platform_get_drvdata(pdev);
|
|
|
|
|
DEBUG;
|
|
|
|
|
clk_enable(hw->clk);
|
|
|
|
|
|
|
|
|
|
s3c_spi_wifi_if_on();
|
|
|
|
|
@@ -1293,16 +1666,20 @@ static struct platform_driver s3c_spi_driver = {
|
|
|
|
|
|
|
|
|
|
static int __init s3c_spi_driver_init(void)
|
|
|
|
|
{
|
|
|
|
|
printk(KERN_INFO "S3C2443 HSPI Driver \n");
|
|
|
|
|
// printk("s3c_spi_driver_init()\n");
|
|
|
|
|
DEBUG;
|
|
|
|
|
|
|
|
|
|
s3c_spi_wifi_if_on();
|
|
|
|
|
|
|
|
|
|
printk("platform_bus_type=%s\n",platform_bus_type.name);
|
|
|
|
|
return platform_driver_register(&s3c_spi_driver);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void __exit s3c_spi_driver_exit(void)
|
|
|
|
|
{
|
|
|
|
|
printk("s3c_spi_driver_exit()++\n");
|
|
|
|
|
s3c_spi_wifi_if_off();
|
|
|
|
|
platform_driver_unregister(&s3c_spi_driver);
|
|
|
|
|
printk("s3c_spi_driver_exit()--\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module_init(s3c_spi_driver_init);
|
|
|
|
|
|