Skip to content

Commit

Permalink
spi: spi-mpc512x-psc: add support for gpio chip selects
Browse files Browse the repository at this point in the history
Currently the driver only uses one internal chip select.
Add support for gpio chip selects configured by cs-gpios
DT binding.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Anatolij Gustschin authored and Mark Brown committed Apr 9, 2013
1 parent ab300d1 commit 86e9874
Showing 1 changed file with 25 additions and 6 deletions.
31 changes: 25 additions & 6 deletions drivers/spi/spi-mpc512x-psc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/clk.h>
#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
#include <linux/gpio.h>
#include <asm/mpc52xx_psc.h>

struct mpc512x_psc_spi {
Expand Down Expand Up @@ -113,15 +114,15 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
out_be32(&psc->ccr, ccr);
mps->bits_per_word = cs->bits_per_word;

if (mps->cs_control)
if (mps->cs_control && gpio_is_valid(spi->cs_gpio))
mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
}

static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi)
{
struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);

if (mps->cs_control)
if (mps->cs_control && gpio_is_valid(spi->cs_gpio))
mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1);

}
Expand Down Expand Up @@ -278,6 +279,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi)
struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
struct mpc512x_psc_spi_cs *cs = spi->controller_state;
unsigned long flags;
int ret;

if (spi->bits_per_word % 8)
return -EINVAL;
Expand All @@ -286,6 +288,19 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi)
cs = kzalloc(sizeof *cs, GFP_KERNEL);
if (!cs)
return -ENOMEM;

if (gpio_is_valid(spi->cs_gpio)) {
ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev));
if (ret) {
dev_err(&spi->dev, "can't get CS gpio: %d\n",
ret);
kfree(cs);
return ret;
}
gpio_direction_output(spi->cs_gpio,
spi->mode & SPI_CS_HIGH ? 0 : 1);
}

spi->controller_state = cs;
}

Expand Down Expand Up @@ -319,6 +334,8 @@ static int mpc512x_psc_spi_transfer(struct spi_device *spi,

static void mpc512x_psc_spi_cleanup(struct spi_device *spi)
{
if (gpio_is_valid(spi->cs_gpio))
gpio_free(spi->cs_gpio);
kfree(spi->controller_state);
}

Expand Down Expand Up @@ -405,6 +422,11 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
return IRQ_NONE;
}

static void mpc512x_spi_cs_control(struct spi_device *spi, bool onoff)
{
gpio_set_value(spi->cs_gpio, onoff);
}

/* bus_num is used only for the case dev->platform_data == NULL */
static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
u32 size, unsigned int irq,
Expand All @@ -425,12 +447,9 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
mps->irq = irq;

if (pdata == NULL) {
dev_err(dev, "probe called without platform data, no "
"cs_control function will be called\n");
mps->cs_control = NULL;
mps->cs_control = mpc512x_spi_cs_control;
mps->sysclk = 0;
master->bus_num = bus_num;
master->num_chipselect = 255;
} else {
mps->cs_control = pdata->cs_control;
mps->sysclk = pdata->sysclk;
Expand Down

0 comments on commit 86e9874

Please sign in to comment.