|
@@ -170,8 +170,7 @@ struct sirfsoc_spi {
|
|
|
* command model
|
|
|
*/
|
|
|
bool tx_by_cmd;
|
|
|
-
|
|
|
- int chipselect[0];
|
|
|
+ bool hw_cs;
|
|
|
};
|
|
|
|
|
|
static void spi_sirfsoc_rx_word_u8(struct sirfsoc_spi *sspi)
|
|
@@ -484,7 +483,7 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value)
|
|
|
{
|
|
|
struct sirfsoc_spi *sspi = spi_master_get_devdata(spi->master);
|
|
|
|
|
|
- if (sspi->chipselect[spi->chip_select] == 0) {
|
|
|
+ if (sspi->hw_cs) {
|
|
|
u32 regval = readl(sspi->base + SIRFSOC_SPI_CTRL);
|
|
|
switch (value) {
|
|
|
case BITBANG_CS_ACTIVE:
|
|
@@ -502,14 +501,13 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value)
|
|
|
}
|
|
|
writel(regval, sspi->base + SIRFSOC_SPI_CTRL);
|
|
|
} else {
|
|
|
- int gpio = sspi->chipselect[spi->chip_select];
|
|
|
switch (value) {
|
|
|
case BITBANG_CS_ACTIVE:
|
|
|
- gpio_direction_output(gpio,
|
|
|
+ gpio_direction_output(spi->cs_gpio,
|
|
|
spi->mode & SPI_CS_HIGH ? 1 : 0);
|
|
|
break;
|
|
|
case BITBANG_CS_INACTIVE:
|
|
|
- gpio_direction_output(gpio,
|
|
|
+ gpio_direction_output(spi->cs_gpio,
|
|
|
spi->mode & SPI_CS_HIGH ? 0 : 1);
|
|
|
break;
|
|
|
}
|
|
@@ -603,8 +601,8 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
|
|
|
sspi->tx_by_cmd = false;
|
|
|
}
|
|
|
/*
|
|
|
- * set spi controller in RISC chipselect mode, we are controlling CS by
|
|
|
- * software BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE.
|
|
|
+ * it should never set to hardware cs mode because in hardware cs mode,
|
|
|
+ * cs signal can't controlled by driver.
|
|
|
*/
|
|
|
regval |= SIRFSOC_SPI_CS_IO_MODE;
|
|
|
writel(regval, sspi->base + SIRFSOC_SPI_CTRL);
|
|
@@ -627,9 +625,17 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
|
|
|
|
|
|
static int spi_sirfsoc_setup(struct spi_device *spi)
|
|
|
{
|
|
|
+ struct sirfsoc_spi *sspi;
|
|
|
+
|
|
|
if (!spi->max_speed_hz)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ sspi = spi_master_get_devdata(spi->master);
|
|
|
+
|
|
|
+ if (spi->cs_gpio == -ENOENT)
|
|
|
+ sspi->hw_cs = true;
|
|
|
+ else
|
|
|
+ sspi->hw_cs = false;
|
|
|
return spi_sirfsoc_setup_transfer(spi, NULL);
|
|
|
}
|
|
|
|
|
@@ -638,19 +644,10 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
|
|
|
struct sirfsoc_spi *sspi;
|
|
|
struct spi_master *master;
|
|
|
struct resource *mem_res;
|
|
|
- int num_cs, cs_gpio, irq;
|
|
|
- int i;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = of_property_read_u32(pdev->dev.of_node,
|
|
|
- "sirf,spi-num-chipselects", &num_cs);
|
|
|
- if (ret < 0) {
|
|
|
- dev_err(&pdev->dev, "Unable to get chip select number\n");
|
|
|
- goto err_cs;
|
|
|
- }
|
|
|
+ int irq;
|
|
|
+ int i, ret;
|
|
|
|
|
|
- master = spi_alloc_master(&pdev->dev,
|
|
|
- sizeof(*sspi) + sizeof(int) * num_cs);
|
|
|
+ master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
|
|
|
if (!master) {
|
|
|
dev_err(&pdev->dev, "Unable to allocate SPI master\n");
|
|
|
return -ENOMEM;
|
|
@@ -658,32 +655,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
|
|
|
platform_set_drvdata(pdev, master);
|
|
|
sspi = spi_master_get_devdata(master);
|
|
|
|
|
|
- master->num_chipselect = num_cs;
|
|
|
-
|
|
|
- for (i = 0; i < master->num_chipselect; i++) {
|
|
|
- cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", i);
|
|
|
- if (cs_gpio < 0) {
|
|
|
- dev_err(&pdev->dev, "can't get cs gpio from DT\n");
|
|
|
- ret = -ENODEV;
|
|
|
- goto free_master;
|
|
|
- }
|
|
|
-
|
|
|
- sspi->chipselect[i] = cs_gpio;
|
|
|
- if (cs_gpio == 0)
|
|
|
- continue; /* use cs from spi controller */
|
|
|
-
|
|
|
- ret = gpio_request(cs_gpio, DRIVER_NAME);
|
|
|
- if (ret) {
|
|
|
- while (i > 0) {
|
|
|
- i--;
|
|
|
- if (sspi->chipselect[i] > 0)
|
|
|
- gpio_free(sspi->chipselect[i]);
|
|
|
- }
|
|
|
- dev_err(&pdev->dev, "fail to request cs gpios\n");
|
|
|
- goto free_master;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
sspi->base = devm_ioremap_resource(&pdev->dev, mem_res);
|
|
|
if (IS_ERR(sspi->base)) {
|
|
@@ -753,7 +724,21 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
|
|
|
ret = spi_bitbang_start(&sspi->bitbang);
|
|
|
if (ret)
|
|
|
goto free_dummypage;
|
|
|
-
|
|
|
+ for (i = 0; master->cs_gpios && i < master->num_chipselect; i++) {
|
|
|
+ if (master->cs_gpios[i] == -ENOENT)
|
|
|
+ continue;
|
|
|
+ if (!gpio_is_valid(master->cs_gpios[i])) {
|
|
|
+ dev_err(&pdev->dev, "no valid gpio\n");
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto free_dummypage;
|
|
|
+ }
|
|
|
+ ret = devm_gpio_request(&pdev->dev,
|
|
|
+ master->cs_gpios[i], DRIVER_NAME);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&pdev->dev, "failed to request gpio\n");
|
|
|
+ goto free_dummypage;
|
|
|
+ }
|
|
|
+ }
|
|
|
dev_info(&pdev->dev, "registerred, bus number = %d\n", master->bus_num);
|
|
|
|
|
|
return 0;
|
|
@@ -768,7 +753,7 @@ free_rx_dma:
|
|
|
dma_release_channel(sspi->rx_chan);
|
|
|
free_master:
|
|
|
spi_master_put(master);
|
|
|
-err_cs:
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -776,16 +761,11 @@ static int spi_sirfsoc_remove(struct platform_device *pdev)
|
|
|
{
|
|
|
struct spi_master *master;
|
|
|
struct sirfsoc_spi *sspi;
|
|
|
- int i;
|
|
|
|
|
|
master = platform_get_drvdata(pdev);
|
|
|
sspi = spi_master_get_devdata(master);
|
|
|
|
|
|
spi_bitbang_stop(&sspi->bitbang);
|
|
|
- for (i = 0; i < master->num_chipselect; i++) {
|
|
|
- if (sspi->chipselect[i] > 0)
|
|
|
- gpio_free(sspi->chipselect[i]);
|
|
|
- }
|
|
|
kfree(sspi->dummypage);
|
|
|
clk_disable_unprepare(sspi->clk);
|
|
|
clk_put(sspi->clk);
|