Re: FSL SPI driver question

2012-01-26 Thread Norbert van Bolhuis

Hi Bruce,


On 01/25/12 20:49, bruce_leon...@selinc.com wrote:
.
.
.

Thanks for the reply.  Yes I did find spidev_fdx.c and in fact copied it
for my tests.  I still see SPICLK active only during the time the 8308 is
sending data (read cmd + address).  Nothing happens with the clock after
that when the NvRAM is ready to send data.

Bruce




ok, then I don't know.

I doubt this is a spidev or FSP SPI driver problem though.

Questions like:

Could it be a HW problem ?
Is the correct SPI mode used ?
Does it work in u-boot ?

Come to mind in a situation like this.


Norbert.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: FSL SPI driver question

2012-01-26 Thread Bruce_Leonard
Norbert,

 
 ok, then I don't know.
 
 I doubt this is a spidev or FSP SPI driver problem though.
 
 Questions like:
 
 Could it be a HW problem ?
 Is the correct SPI mode used ?
 Does it work in u-boot ?
 
 Come to mind in a situation like this.
 

Thanks for the suggestions.  I finally found it in the wee hours this 
morning, and it was operator error.  The CY14 by default powers up in the 
write protect state and from the factory is erased to all zeros.  So my 
writes and subsequent reads appeared to fail by the fact that I could 
never read what I wrote.  Guess I need better reading glasses in my old 
age :-/

Anyway, I'm happily up and talking using the Freescale SPI driver and 
spidev.  Thanks for the help and sorry for the noise on the list.

Bruce
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Another FSL SPI driver question (warning long post)

2012-01-26 Thread Bruce_Leonard
Hi Kumar,

I'm using the 3.0.3 kernel on an MPC8308 and utilizing the spi_fsl_spi 
driver to talk with an Cypress NvRAM device.  I've gotten that working 
now, but I've come across something I don't understand in the driver and 
I'm not sure if it's just me or if there's a bug.  My issue relates to 
chip selects, their active state, and their specification in the device 
tree (lots of moving parts here, so I hope I describe it well enough to be 
understood).  The chip select for the NvRAM is active low, but setting 
everything up they way I _think_ it should be for an active low signal 
gets me an active high signal. 

The device tree entry is:

  spi@7000 {
 #address-cells = 1;
 #size-cells = 0;
 cell-index = 0;
 compatible = fsl,spi;
 reg = 0x7000 0x1000;
 interrupts = 16 0x8;
 interrupt-parent = ipic;
 mode = cpu;
 gpios = gpio1 16 1;

 nvram@0 {
compatible = spidev;
spi-max-frequency = 4000;
reg = 0;
 };
  };

And the relevant driver code is the fsl_spi_chipselect and the 
fsl_spi_cs_control functions shown below (line numbers are for reference 
only and don't match lines numbers in .../drivers/spi/spi_fsl_spi.c):

1  static void fsl_spi_chipselect(struct spi_device *spi, int value)
2  {
3   struct mpc8xxx_spi *mpc8xxx_spi = 
spi_master_get_devdata(spi-master);
4   struct fsl_spi_platform_data *pdata = 
spi-dev.parent-platform_data;
5   bool pol = spi-mode  SPI_CS_HIGH;
6   struct spi_mpc8xxx_cs   *cs = spi-controller_state;
7 
8   if (value == BITBANG_CS_INACTIVE) {
9   if (pdata-cs_control)
10  pdata-cs_control(spi, !pol);
11  }
12
13  if (value == BITBANG_CS_ACTIVE) {
14  mpc8xxx_spi-rx_shift = cs-rx_shift;
15  mpc8xxx_spi-tx_shift = cs-tx_shift;
16  mpc8xxx_spi-get_rx = cs-get_rx;
17  mpc8xxx_spi-get_tx = cs-get_tx;
18
19  fsl_spi_change_mode(spi);
20
21  if (pdata-cs_control)
22  pdata-cs_control(spi, pol);
23  }
24 }
25
26 static void fsl_spi_cs_control(struct spi_device *spi, bool on)
27 {
28  struct device *dev = spi-dev.parent;
29  struct mpc8xxx_spi_probe_info *pinfo = 
to_of_pinfo(dev-platform_data);
30  u16 cs = spi-chip_select;
31  int gpio = pinfo-gpios[cs];
32  bool alow = pinfo-alow_flags[cs];
33
34  gpio_set_value(gpio, on ^ alow);
35 }

The variable pol comes from spi-mode  SPI_CS_HIGH (line 5) and 
spi-mode gets it's value based on the spi-cs-high attribute in the device 
tree via .../drivers/of/of_spi.c like this:

if (of_find_property(nc, spi-cs-high, NULL))
spi-mode |= SPI_CS_HIGH;

In my case I want an active low CS so I don't include this attribute and 
spi-mode doesn't get the bit set.  alow (line 32) ultimately comes from 
the flags part of the gpios specifier in the SPI node of my device tree 
via the of_fsl_spi_probe function like this:

gpio = of_get_gpio_flags(np, i, flags);  - flags gets a direct copy of 
flags in the gpios specifier
pinfo-alow_flags[i] = flags  OF_GPIO_ACTIVE_LOW;

OF_GPIO_ACTIVE_LOW is an enum with a value of 0x1, implying that a value 
of 1 in the flags in my gpios specifier is saying the GPIO signal is 
active low.  So if my understanding is right, I've got everything set up 
in my device tree correctly to have an active low CS.

Now to the crux of the problem, line 34, the gpio_set_value call.  When an 
SPI transaction is started and the CS needs to be driven to it's active 
state (low in my case) fsl_spi_chipselect is called with value = 
BITBANG_CS_ACTIVE, which leads to line 22, calling fsl_spi_cs_control with 
pol = 0 because spi-mode doesn't have the SPI_CS_HIGH bit set (line 5) 
which becomes on in fsl_spi_cs_control.  alow = 1(line 32) because flags 
is 1 in the gpios specifier.  on = 0 XORed with alow = 1 equals 1 when 
gpio_set_value is called, setting my chipselect HIGH not low.  Then when 
the transaction is done fsl_spi_chipselect is called with value = 
BITBANG_CS_INACTIVE which leads to line 10 calling fsl_spi_cs_control with 
!pol = 1, alow is still a 1 and 1 XOR 1 = 0 when gpio_set_value is called, 
setting my chipselect to LOW.

I did an experiment in which I added the spi-cs-high attribute to my 
device tree (which should have made the signal active high) and the result 
was the signal operated in the opposite way from what the name of the 
attribute implies.

So (if my understanding of the device tree entries is correct) the logic 
on line 34 appears to be flawed, but since I'm not 100% sure of my 
understanding I wanted to ask people smarter than I am.

More over, I don't think I understand why a device tree entry is used to 
indicate which state to change the chipselect to.  Wouldn't it make more 
sense if lines 10 and 22 pass in a 1 for set the CS to the active 
state and a 0 for set the CS to the inactive 

Re: FSL SPI driver question

2012-01-25 Thread Norbert van Bolhuis

On 01/25/12 01:11, bruce_leon...@selinc.com wrote:

Good afternoon,

I'm using the 3.0.3 kernel running on an MPC8308 and am trying to
interface to a Cypress CY14B256Q2A non-volatile RAM via SPI.  I've got the
SPI infrastructure, the Freescale SPI driver (drivers/spi/spi_fsl_spi.c),
and spidev built into the kernel and everything on the user space/kernel
side appears to be working correctly (at least when I try to read the
NvRAM's config register all the right places in the kernel get hit and I
see the SPI signals active with an o-scope).

I think what I'm hitting is a lack of understanding/documentation on the
SPI controller in the 8308.  To read data from the NvRAM, the Master (the
8308 in this case) needs to clock out a byte long read command, two
bytes of address, and then clock in the data from the NvRAM.  However, I
never get any data back.  I think the problem is that (direct quote from
the 8308 reference manual) SPICLK is a gated clock, active only during
data transfers.  So once the read command and address are sent, the 8308
considers the data transfer complete and gates off SPICLK.  Without
SPICLK, the NvRAM has no way to clock out it's data.  I think it's ready
to, it just can't.

So the question is, how do I use spidev (or any other means) to get the
8308 SPI controller to keep SPICLK active so that the output data from the
NvRAM gets clocked out to the 8308?

Thanks.

Bruce



Did you see Documentation/spi/spidev_fdx.c:do_msg ?
it perform a full-duplex (actually half-duplex) 1 byte transfer.

In your case you need a transfer that outputs 3 bytes (read cmd + address)
and inputs 1? byte.

If you do it this way I would expect the SPICLK to be active
during the 2nd part of the transfer (whenever the CPU reads the
data from SPI client).

hth.

---
NvBolhuis
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: FSL SPI driver question

2012-01-25 Thread Bruce_Leonard
Hi Norbert,

 
  So the question is, how do I use spidev (or any other means) to get 
the
  8308 SPI controller to keep SPICLK active so that the output data from 
the
  NvRAM gets clocked out to the 8308?
 
 
 Did you see Documentation/spi/spidev_fdx.c:do_msg ?
 it perform a full-duplex (actually half-duplex) 1 byte transfer.
 
 In your case you need a transfer that outputs 3 bytes (read cmd + 
address)
 and inputs 1? byte.
 
 If you do it this way I would expect the SPICLK to be active
 during the 2nd part of the transfer (whenever the CPU reads the
 data from SPI client).
 

Thanks for the reply.  Yes I did find spidev_fdx.c and in fact copied it 
for my tests.  I still see SPICLK active only during the time the 8308 is 
sending data (read cmd + address).  Nothing happens with the clock after 
that when the NvRAM is ready to send data.

Bruce
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


FSL SPI driver question

2012-01-24 Thread Bruce_Leonard
Good afternoon,

I'm using the 3.0.3 kernel running on an MPC8308 and am trying to 
interface to a Cypress CY14B256Q2A non-volatile RAM via SPI.  I've got the 
SPI infrastructure, the Freescale SPI driver (drivers/spi/spi_fsl_spi.c), 
and spidev built into the kernel and everything on the user space/kernel 
side appears to be working correctly (at least when I try to read the 
NvRAM's config register all the right places in the kernel get hit and I 
see the SPI signals active with an o-scope).

I think what I'm hitting is a lack of understanding/documentation on the 
SPI controller in the 8308.  To read data from the NvRAM, the Master (the 
8308 in this case) needs to clock out a byte long read command, two 
bytes of address, and then clock in the data from the NvRAM.  However, I 
never get any data back.  I think the problem is that (direct quote from 
the 8308 reference manual) SPICLK is a gated clock, active only during 
data transfers.  So once the read command and address are sent, the 8308 
considers the data transfer complete and gates off SPICLK.  Without 
SPICLK, the NvRAM has no way to clock out it's data.  I think it's ready 
to, it just can't.

So the question is, how do I use spidev (or any other means) to get the 
8308 SPI controller to keep SPICLK active so that the output data from the 
NvRAM gets clocked out to the 8308?

Thanks.

Bruce
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev