RE: Help Melinda with a 2.6 spi driver for mpc875!

2007-03-06 Thread DI BACCO ANTONIO - technolabs

I attached a driver for the SPI controller of MPC875 that I'm
developing. It's not yet complete, actually, in the mpc8xx_transfer ()
method simply tries to transmit 3 bytes (the SPI controller is looped)
and thus I 

Hi Melinda,

I saw that you are using __pa() to convert virtual to physical addresses
for the rx and tx buffers. I had a lot of problems with it. I used it in
2.4 but now it seems to have strange effects.

Bye,
Antonio.
___
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded


Help Melinda with a 2.6 spi driver for mpc875!

2007-03-05 Thread melinda develey
Hi,

I attached a driver for the SPI controller of MPC875 that I'm developing. It's 
not yet complete, actually, in the mpc8xx_transfer () method simply tries to 
transmit 3 bytes (the SPI controller is looped) and thus I expect to receive 
the same three bytes. It works sometimes, but not always and I don't know why. 
In the init I configure the SPI controller, to do this, I do a ioremap_nocache 
of  physaddr IMMAP address and then write the relevant registers. I also tried 
to put __iomem qualifier to the SPI registers pointers thinking that the writes 
to the SPI registers were cached. No success! What could be the problem?

Bye,
Melinda.


 
-
Everyone is raving about the all-new Yahoo! Mail beta./*
 * MPC83xx SPI controller driver.
 *
 * Maintainer: Kumar Gala
 *
 * Copyright (C) 2006 Polycom, Inc.
 *
 * 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.
 */
#include linux/module.h
#include linux/init.h
#include linux/types.h
#include linux/kernel.h
#include linux/completion.h
#include linux/interrupt.h
#include linux/delay.h
#include linux/irq.h
#include linux/dma-mapping.h
#include linux/device.h
#include linux/spi/spi.h
#include linux/spi/spi_bitbang.h
#include linux/platform_device.h
#include linux/fsl_devices.h
#include linux/fs_spi_pd.h
#include asm/irq.h
#include asm/io.h
#include asm/commproc.h


/* MPC8xx SPI Controller mode register definitions are in commproc.h */
#define	SPMODE_LEN(x)		((x-1)  4)
#define	SPMODE_PM(x)		((x))

#define SPI_MAX_BUFFER_SIZE 32
/*
 * Default for SPI Mode:
 * 	SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
 */
#define	SPMODE_INIT_VAL (SPMODE_CI | SPMODE_DIV16 | SPMODE_REV | \
			 SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf))

/* SPIE/SPIM register values */
#define	SPIE_MME		0x20	/* Multimaster error */
#define	SPIE_TXE		0x10	/* Tx error */
#define	SPIE_BSY		0x04/* No rx buffer available */
#define	SPIE_TXB		0x02/* Tx buffer transmitted */
#define	SPIE_NF		0x01/* Rx buffer filled */

/* SPCOM values */
#define SPCOM_START 0x80/* Start transmission command */

#ifndef BD_SC_ME
#define BD_SC_ME((ushort)0x0001)/* Multi Master Error */
#endif

/*/


int j = 0;
static u8* rxbuffer;
static u8* txbuffer;
void spi_activate_cs(u8 cs, u8 polarity);
void spi_deactivate_cs(u8 cs, u8 polarity);

static car8xx_t *carp; 
static spi_t	*spi;  
static immap_t  *immap;
static cpic8xx_t*cpi;  
static cpm8xx_t *cp;   
static iop8xx_t *iop;  
static cbd_t*tbdf;
static cbd_t*rbdf;

static  unsigned short r_tbase, r_rbase;

/* SPI Controller driver's private data. */
struct mpc8xx_spi {

	struct completion done;

dma_addr_t scratchbuf;

/* lock to avoid contemporaneous transmission */
spinlock_t lock;

	unsigned int count;
	u32 irq;

	unsigned nsecs;		/* (clock cycle time)/2 */

	u32 inpclk;

u16 mode; /* spi mode in hardware specific way */

	void (*activate_cs) (u8 cs, u8 polarity);
	void (*deactivate_cs) (u8 cs, u8 polarity);

};



static 
u16 mpc8xx_spi_hwmode(u8 mode, int len, u32 inpclk, u32 speedhz)
{
/* DFBRG is zero */
u16 modehw = SPMODE_MSTR ;

/* setup spi mode */
if (mode  SPI_CPOL)
modehw |= SPMODE_CI;   
if (mode  SPI_CPHA)
modehw |= SPMODE_CP; 
if (!(mode  SPI_LSB_FIRST))
modehw |= SPMODE_REV;   
   
modehw |= SPMODE_LEN(len); 

/* Setting desired speed */
modehw |= SPMODE_PM((u8)((inpclk/speedhz)/4-1));
 
return modehw;
}

static
int mpc8xx_transmit(u8* tx_buf, u8* rx_buf, int tx_size, int rx_size)
{
	int result, i;
	
// copy data to be sent into the transmit buffer
	if (tx_buf)
  memcpy((void*)(txbuffer), (void*)tx_buf, tx_size);

// BD data length register
tbdf-cbd_datlen = rbdf-cbd_datlen = tx_size + rx_size;


printk(SPI TX: );
for (i = 0; i  tx_size; i++)
  printk(%02X , txbuffer[i]);
printk(\n);

	 // BD status/control register
	tbdf-cbd_sc = BD_SC_READY | BD_SC_WRAP | BD_SC_LAST;
	rbdf-cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;

	cp-cp_spmode = 0x4678;   // spi mode setting
	cp-cp_spmode |= 0x0100;// enable SPI
	cp-cp_spie   = 0xff;   // clear all spi events
	cp-cp_spim   = 0x37;   // mask all SPI events


	udelay(10); // Wait 5 microsecs

	cp-cp_spcom = 0x80;   // start the transfer

	udelay(10);

	cp-cp_spmode = 0x00;   // reset spi mode

	udelay(10); // Wait 10 microsecs


	// test receive and transmit buffer descriptor for errors
	if