Merge branch 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[cascardo/linux.git] / drivers / spi / spi-pxa2xx.c
index 87150a1..dd7b5b4 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/spi/spi.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
@@ -62,6 +63,13 @@ MODULE_ALIAS("platform:pxa2xx-spi");
                                | QUARK_X1000_SSCR1_TFT         \
                                | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
 
+#define CE4100_SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \
+                               | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \
+                               | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \
+                               | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \
+                               | CE4100_SSCR1_RFT | CE4100_SSCR1_TFT | SSCR1_MWDS \
+                               | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
+
 #define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE  BIT(24)
 #define LPSS_CS_CONTROL_SW_MODE                        BIT(0)
 #define LPSS_CS_CONTROL_CS_HIGH                        BIT(1)
@@ -175,6 +183,8 @@ static u32 pxa2xx_spi_get_ssrc1_change_mask(const struct driver_data *drv_data)
        switch (drv_data->ssp_type) {
        case QUARK_X1000_SSP:
                return QUARK_X1000_SSCR1_CHANGE_MASK;
+       case CE4100_SSP:
+               return CE4100_SSCR1_CHANGE_MASK;
        default:
                return SSCR1_CHANGE_MASK;
        }
@@ -186,6 +196,8 @@ pxa2xx_spi_get_rx_default_thre(const struct driver_data *drv_data)
        switch (drv_data->ssp_type) {
        case QUARK_X1000_SSP:
                return RX_THRESH_QUARK_X1000_DFLT;
+       case CE4100_SSP:
+               return RX_THRESH_CE4100_DFLT;
        default:
                return RX_THRESH_DFLT;
        }
@@ -199,6 +211,9 @@ static bool pxa2xx_spi_txfifo_full(const struct driver_data *drv_data)
        case QUARK_X1000_SSP:
                mask = QUARK_X1000_SSSR_TFL_MASK;
                break;
+       case CE4100_SSP:
+               mask = CE4100_SSSR_TFL_MASK;
+               break;
        default:
                mask = SSSR_TFL_MASK;
                break;
@@ -216,6 +231,9 @@ static void pxa2xx_spi_clear_rx_thre(const struct driver_data *drv_data,
        case QUARK_X1000_SSP:
                mask = QUARK_X1000_SSCR1_RFT;
                break;
+       case CE4100_SSP:
+               mask = CE4100_SSCR1_RFT;
+               break;
        default:
                mask = SSCR1_RFT;
                break;
@@ -230,6 +248,9 @@ static void pxa2xx_spi_set_rx_thre(const struct driver_data *drv_data,
        case QUARK_X1000_SSP:
                *sccr1_reg |= QUARK_X1000_SSCR1_RxTresh(threshold);
                break;
+       case CE4100_SSP:
+               *sccr1_reg |= CE4100_SSCR1_RxTresh(threshold);
+               break;
        default:
                *sccr1_reg |= SSCR1_RxTresh(threshold);
                break;
@@ -316,7 +337,7 @@ static void lpss_ssp_select_cs(struct driver_data *drv_data,
 
        value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl);
 
-       cs = drv_data->cur_msg->spi->chip_select;
+       cs = drv_data->master->cur_msg->spi->chip_select;
        cs <<= config->cs_sel_shift;
        if (cs != (value & config->cs_sel_mask)) {
                /*
@@ -355,10 +376,11 @@ static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
 
 static void cs_assert(struct driver_data *drv_data)
 {
-       struct chip_data *chip = drv_data->cur_chip;
+       struct chip_data *chip =
+               spi_get_ctldata(drv_data->master->cur_msg->spi);
 
        if (drv_data->ssp_type == CE4100_SSP) {
-               pxa2xx_spi_write(drv_data, SSSR, drv_data->cur_chip->frm);
+               pxa2xx_spi_write(drv_data, SSSR, chip->frm);
                return;
        }
 
@@ -378,7 +400,8 @@ static void cs_assert(struct driver_data *drv_data)
 
 static void cs_deassert(struct driver_data *drv_data)
 {
-       struct chip_data *chip = drv_data->cur_chip;
+       struct chip_data *chip =
+               spi_get_ctldata(drv_data->master->cur_msg->spi);
 
        if (drv_data->ssp_type == CE4100_SSP)
                return;
@@ -508,7 +531,7 @@ static int u32_reader(struct driver_data *drv_data)
 
 void *pxa2xx_spi_next_transfer(struct driver_data *drv_data)
 {
-       struct spi_message *msg = drv_data->cur_msg;
+       struct spi_message *msg = drv_data->master->cur_msg;
        struct spi_transfer *trans = drv_data->cur_transfer;
 
        /* Move to next transfer */
@@ -529,8 +552,7 @@ static void giveback(struct driver_data *drv_data)
        struct spi_message *msg;
        unsigned long timeout;
 
-       msg = drv_data->cur_msg;
-       drv_data->cur_msg = NULL;
+       msg = drv_data->master->cur_msg;
        drv_data->cur_transfer = NULL;
 
        last_transfer = list_last_entry(&msg->transfers, struct spi_transfer,
@@ -575,13 +597,13 @@ static void giveback(struct driver_data *drv_data)
                        cs_deassert(drv_data);
        }
 
-       drv_data->cur_chip = NULL;
        spi_finalize_current_message(drv_data->master);
 }
 
 static void reset_sccr1(struct driver_data *drv_data)
 {
-       struct chip_data *chip = drv_data->cur_chip;
+       struct chip_data *chip =
+               spi_get_ctldata(drv_data->master->cur_msg->spi);
        u32 sccr1_reg;
 
        sccr1_reg = pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1;
@@ -589,6 +611,9 @@ static void reset_sccr1(struct driver_data *drv_data)
        case QUARK_X1000_SSP:
                sccr1_reg &= ~QUARK_X1000_SSCR1_RFT;
                break;
+       case CE4100_SSP:
+               sccr1_reg &= ~CE4100_SSCR1_RFT;
+               break;
        default:
                sccr1_reg &= ~SSCR1_RFT;
                break;
@@ -610,7 +635,7 @@ static void int_error_stop(struct driver_data *drv_data, const char* msg)
 
        dev_err(&drv_data->pdev->dev, "%s\n", msg);
 
-       drv_data->cur_msg->state = ERROR_STATE;
+       drv_data->master->cur_msg->state = ERROR_STATE;
        tasklet_schedule(&drv_data->pump_transfers);
 }
 
@@ -623,7 +648,7 @@ static void int_transfer_complete(struct driver_data *drv_data)
                pxa2xx_spi_write(drv_data, SSTO, 0);
 
        /* Update total byte transferred return count actual bytes read */
-       drv_data->cur_msg->actual_length += drv_data->len -
+       drv_data->master->cur_msg->actual_length += drv_data->len -
                                (drv_data->rx_end - drv_data->rx);
 
        /* Transfer delays and chip select release are
@@ -631,7 +656,7 @@ static void int_transfer_complete(struct driver_data *drv_data)
         */
 
        /* Move to next transfer */
-       drv_data->cur_msg->state = pxa2xx_spi_next_transfer(drv_data);
+       drv_data->master->cur_msg->state = pxa2xx_spi_next_transfer(drv_data);
 
        /* Schedule transfer tasklet */
        tasklet_schedule(&drv_data->pump_transfers);
@@ -746,7 +771,7 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
        if (!(status & mask))
                return IRQ_NONE;
 
-       if (!drv_data->cur_msg) {
+       if (!drv_data->master->cur_msg) {
 
                pxa2xx_spi_write(drv_data, SSCR0,
                                 pxa2xx_spi_read(drv_data, SSCR0)
@@ -905,7 +930,8 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
 static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
                                           int rate)
 {
-       struct chip_data *chip = drv_data->cur_chip;
+       struct chip_data *chip =
+               spi_get_ctldata(drv_data->master->cur_msg->spi);
        unsigned int clk_div;
 
        switch (drv_data->ssp_type) {
@@ -934,25 +960,23 @@ static void pump_transfers(unsigned long data)
 {
        struct driver_data *drv_data = (struct driver_data *)data;
        struct spi_master *master = drv_data->master;
-       struct spi_message *message = NULL;
-       struct spi_transfer *transfer = NULL;
-       struct spi_transfer *previous = NULL;
-       struct chip_data *chip = NULL;
-       u32 clk_div = 0;
-       u8 bits = 0;
-       u32 speed = 0;
+       struct spi_message *message = master->cur_msg;
+       struct chip_data *chip = spi_get_ctldata(message->spi);
+       u32 dma_thresh = chip->dma_threshold;
+       u32 dma_burst = chip->dma_burst_size;
+       u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
+       struct spi_transfer *transfer;
+       struct spi_transfer *previous;
+       u32 clk_div;
+       u8 bits;
+       u32 speed;
        u32 cr0;
        u32 cr1;
-       u32 dma_thresh = drv_data->cur_chip->dma_threshold;
-       u32 dma_burst = drv_data->cur_chip->dma_burst_size;
-       u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
        int err;
        int dma_mapped;
 
        /* Get current state information */
-       message = drv_data->cur_msg;
        transfer = drv_data->cur_transfer;
-       chip = drv_data->cur_chip;
 
        /* Handle for abort */
        if (message->state == ERROR_STATE) {
@@ -1146,17 +1170,12 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master,
 {
        struct driver_data *drv_data = spi_master_get_devdata(master);
 
-       drv_data->cur_msg = msg;
        /* Initial message state*/
-       drv_data->cur_msg->state = START_STATE;
-       drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
+       msg->state = START_STATE;
+       drv_data->cur_transfer = list_entry(msg->transfers.next,
                                                struct spi_transfer,
                                                transfer_list);
 
-       /* prepare to setup the SSP, in pump_transfers, using the per
-        * chip configuration */
-       drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
-
        /* Mark as busy and launch transfers */
        tasklet_schedule(&drv_data->pump_transfers);
        return 0;
@@ -1176,9 +1195,26 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master)
 static int setup_cs(struct spi_device *spi, struct chip_data *chip,
                    struct pxa2xx_spi_chip *chip_info)
 {
+       struct driver_data *drv_data = spi_master_get_devdata(spi->master);
        int err = 0;
 
-       if (chip == NULL || chip_info == NULL)
+       if (chip == NULL)
+               return 0;
+
+       if (drv_data->cs_gpiods) {
+               struct gpio_desc *gpiod;
+
+               gpiod = drv_data->cs_gpiods[spi->chip_select];
+               if (gpiod) {
+                       chip->gpio_cs = desc_to_gpio(gpiod);
+                       chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
+                       gpiod_set_value(gpiod, chip->gpio_cs_inverted);
+               }
+
+               return 0;
+       }
+
+       if (chip_info == NULL)
                return 0;
 
        /* NOTE: setup() can be called multiple times, possibly with
@@ -1213,7 +1249,7 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip,
 
 static int setup(struct spi_device *spi)
 {
-       struct pxa2xx_spi_chip *chip_info = NULL;
+       struct pxa2xx_spi_chip *chip_info;
        struct chip_data *chip;
        const struct lpss_config *config;
        struct driver_data *drv_data = spi_master_get_devdata(spi->master);
@@ -1225,6 +1261,11 @@ static int setup(struct spi_device *spi)
                tx_hi_thres = 0;
                rx_thres = RX_THRESH_QUARK_X1000_DFLT;
                break;
+       case CE4100_SSP:
+               tx_thres = TX_THRESH_CE4100_DFLT;
+               tx_hi_thres = 0;
+               rx_thres = RX_THRESH_CE4100_DFLT;
+               break;
        case LPSS_LPT_SSP:
        case LPSS_BYT_SSP:
        case LPSS_BSW_SSP:
@@ -1309,6 +1350,10 @@ static int setup(struct spi_device *spi)
                                   | (QUARK_X1000_SSCR1_TxTresh(tx_thres)
                                   & QUARK_X1000_SSCR1_TFT);
                break;
+       case CE4100_SSP:
+               chip->threshold = (CE4100_SSCR1_RxTresh(rx_thres) & CE4100_SSCR1_RFT) |
+                       (CE4100_SSCR1_TxTresh(tx_thres) & CE4100_SSCR1_TFT);
+               break;
        default:
                chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
                        (SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
@@ -1352,7 +1397,8 @@ static void cleanup(struct spi_device *spi)
        if (!chip)
                return;
 
-       if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs))
+       if (drv_data->ssp_type != CE4100_SSP && !drv_data->cs_gpiods &&
+           gpio_is_valid(chip->gpio_cs))
                gpio_free(chip->gpio_cs);
 
        kfree(chip);
@@ -1530,7 +1576,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
        struct driver_data *drv_data;
        struct ssp_device *ssp;
        const struct lpss_config *config;
-       int status;
+       int status, count;
        u32 tmp;
 
        platform_info = dev_get_platdata(dev);
@@ -1630,15 +1676,20 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
        pxa2xx_spi_write(drv_data, SSCR0, 0);
        switch (drv_data->ssp_type) {
        case QUARK_X1000_SSP:
-               tmp = QUARK_X1000_SSCR1_RxTresh(RX_THRESH_QUARK_X1000_DFLT)
-                     QUARK_X1000_SSCR1_TxTresh(TX_THRESH_QUARK_X1000_DFLT);
+               tmp = QUARK_X1000_SSCR1_RxTresh(RX_THRESH_QUARK_X1000_DFLT) |
+                     QUARK_X1000_SSCR1_TxTresh(TX_THRESH_QUARK_X1000_DFLT);
                pxa2xx_spi_write(drv_data, SSCR1, tmp);
 
                /* using the Motorola SPI protocol and use 8 bit frame */
-               pxa2xx_spi_write(drv_data, SSCR0,
-                                QUARK_X1000_SSCR0_Motorola
-                                | QUARK_X1000_SSCR0_DataSize(8));
+               tmp = QUARK_X1000_SSCR0_Motorola | QUARK_X1000_SSCR0_DataSize(8);
+               pxa2xx_spi_write(drv_data, SSCR0, tmp);
                break;
+       case CE4100_SSP:
+               tmp = CE4100_SSCR1_RxTresh(RX_THRESH_CE4100_DFLT) |
+                     CE4100_SSCR1_TxTresh(TX_THRESH_CE4100_DFLT);
+               pxa2xx_spi_write(drv_data, SSCR1, tmp);
+               tmp = SSCR0_SCR(2) | SSCR0_Motorola | SSCR0_DataSize(8);
+               pxa2xx_spi_write(drv_data, SSCR0, tmp);
        default:
                tmp = SSCR1_RxTresh(RX_THRESH_DFLT) |
                      SSCR1_TxTresh(TX_THRESH_DFLT);
@@ -1669,6 +1720,39 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
        }
        master->num_chipselect = platform_info->num_chipselect;
 
+       count = gpiod_count(&pdev->dev, "cs");
+       if (count > 0) {
+               int i;
+
+               master->num_chipselect = max_t(int, count,
+                       master->num_chipselect);
+
+               drv_data->cs_gpiods = devm_kcalloc(&pdev->dev,
+                       master->num_chipselect, sizeof(struct gpio_desc *),
+                       GFP_KERNEL);
+               if (!drv_data->cs_gpiods) {
+                       status = -ENOMEM;
+                       goto out_error_clock_enabled;
+               }
+
+               for (i = 0; i < master->num_chipselect; i++) {
+                       struct gpio_desc *gpiod;
+
+                       gpiod = devm_gpiod_get_index(dev, "cs", i,
+                                                    GPIOD_OUT_HIGH);
+                       if (IS_ERR(gpiod)) {
+                               /* Means use native chip select */
+                               if (PTR_ERR(gpiod) == -ENOENT)
+                                       continue;
+
+                               status = (int)PTR_ERR(gpiod);
+                               goto out_error_clock_enabled;
+                       } else {
+                               drv_data->cs_gpiods[i] = gpiod;
+                       }
+               }
+       }
+
        tasklet_init(&drv_data->pump_transfers, pump_transfers,
                     (unsigned long)drv_data);
 
@@ -1742,7 +1826,7 @@ static int pxa2xx_spi_suspend(struct device *dev)
 {
        struct driver_data *drv_data = dev_get_drvdata(dev);
        struct ssp_device *ssp = drv_data->ssp;
-       int status = 0;
+       int status;
 
        status = spi_master_suspend(drv_data->master);
        if (status != 0)
@@ -1759,7 +1843,7 @@ static int pxa2xx_spi_resume(struct device *dev)
 {
        struct driver_data *drv_data = dev_get_drvdata(dev);
        struct ssp_device *ssp = drv_data->ssp;
-       int status = 0;
+       int status;
 
        /* Enable the SSP clock */
        if (!pm_runtime_suspended(dev))