summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJane Wan <Jane.Wan@gainspeed.com>2014-04-16 13:09:39 -0700
committerMark Brown <broonie@linaro.org>2014-04-16 22:04:07 +0100
commitd0fb47a5237d8b9576113568bacfd27892308b62 (patch)
treec47f7624dd288d6f21124ecaae401cd228d27736
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
spi: fsl-espi: Configure FSL eSPI CSBEF and CSAFT
Make FSL eSPI CSnBEF and CSnAFT fields in ESPI_SPMODEn registers (n=0,1,2,3) configurable through device tree. CSnBEF is the chip select setup time. It's the delay in bits from the activation of chip select pin to the first clock for data frame. CSnAFT is the chip select hold time. It's the delay in bits from the last clock for data frame to the deactivation of chip select pin. The FSL eSPI driver hardcodes CSnBEF and CSnAFT to 0. Need to set them to a different value for some device. Signed-off-by: Jane Wan <Jane.Wan@gainspeed.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/spi/fsl-spi.txt6
-rw-r--r--drivers/spi/spi-fsl-espi.c34
2 files changed, 36 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/spi/fsl-spi.txt b/Documentation/devicetree/bindings/spi/fsl-spi.txt
index b032dd76e9d..a2331372068 100644
--- a/Documentation/devicetree/bindings/spi/fsl-spi.txt
+++ b/Documentation/devicetree/bindings/spi/fsl-spi.txt
@@ -42,6 +42,10 @@ Required properties:
- interrupts : should contain eSPI interrupt, the device has one interrupt.
- fsl,espi-num-chipselects : the number of the chipselect signals.
+Optional properties:
+- fsl,csbef: chip select assertion time in bits before frame starts
+- fsl,csaft: chip select negation time in bits after frame ends
+
Example:
spi@110000 {
#address-cells = <1>;
@@ -51,4 +55,6 @@ Example:
interrupts = <53 0x2>;
interrupt-parent = <&mpic>;
fsl,espi-num-chipselects = <4>;
+ fsl,csbef = <1>;
+ fsl,csaft = <1>;
};
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index e767f5831b9..24096c84e9c 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -586,8 +586,10 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
struct spi_master *master;
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
- u32 regval;
- int i, ret = 0;
+ struct device_node *nc;
+ const __be32 *prop;
+ u32 regval, csmode;
+ int i, len, ret = 0;
master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi));
if (!master) {
@@ -634,8 +636,32 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
mpc8xxx_spi_write_reg(&reg_base->event, 0xffffffff);
/* Init eSPI CS mode register */
- for (i = 0; i < pdata->max_chipselect; i++)
- mpc8xxx_spi_write_reg(&reg_base->csmode[i], CSMODE_INIT_VAL);
+ for_each_available_child_of_node(master->dev.of_node, nc) {
+ /* get chip select */
+ prop = of_get_property(nc, "reg", &len);
+ if (!prop || len < sizeof(*prop))
+ continue;
+ i = be32_to_cpup(prop);
+ if (i < 0 || i >= pdata->max_chipselect)
+ continue;
+
+ csmode = CSMODE_INIT_VAL;
+ /* check if CSBEF is set in device tree */
+ prop = of_get_property(nc, "fsl,csbef", &len);
+ if (prop && len >= sizeof(*prop)) {
+ csmode &= ~(CSMODE_BEF(0xf));
+ csmode |= CSMODE_BEF(be32_to_cpup(prop));
+ }
+ /* check if CSAFT is set in device tree */
+ prop = of_get_property(nc, "fsl,csaft", &len);
+ if (prop && len >= sizeof(*prop)) {
+ csmode &= ~(CSMODE_AFT(0xf));
+ csmode |= CSMODE_AFT(be32_to_cpup(prop));
+ }
+ mpc8xxx_spi_write_reg(&reg_base->csmode[i], csmode);
+
+ dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode);
+ }
/* Enable SPI interface */
regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;