Changeset 34168


Ignore:
Timestamp:
2012-11-12T09:22:14+01:00 (5 years ago)
Author:
kaloz
Message:

[cns3xxx]: split spi patch, follow mainline file naming

Location:
trunk/target/linux/cns3xxx
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/cns3xxx/patches-3.3/052-cns3xxx_spi.patch

    r33486 r34168  
    2121 obj-$(CONFIG_SPI_BITBANG)              += spi-bitbang.o 
    2222 obj-$(CONFIG_SPI_BUTTERFLY)            += spi-butterfly.o 
    23 +obj-$(CONFIG_SPI_CNS3XXX)              += spi_cns3xxx.o 
     23+obj-$(CONFIG_SPI_CNS3XXX)              += spi-cns3xxx.o 
    2424 obj-$(CONFIG_SPI_COLDFIRE_QSPI)                += spi-coldfire-qspi.o 
    2525 obj-$(CONFIG_SPI_DAVINCI)              += spi-davinci.o 
    2626 obj-$(CONFIG_SPI_DESIGNWARE)           += spi-dw.o 
    27 --- /dev/null 
    28 +++ b/drivers/spi/spi_cns3xxx.c 
    29 @@ -0,0 +1,449 @@ 
    30 +/******************************************************************************* 
    31 + * 
    32 + *  CNS3XXX SPI controller driver (master mode only) 
    33 + * 
    34 + *  Copyright (c) 2008 Cavium Networks 
    35 + *  Copyright 2011 Gateworks Corporation 
    36 + *                Chris Lang <clang@gateworks.com> 
    37 + * 
    38 + *  This file is free software; you can redistribute it and/or modify 
    39 + *  it under the terms of the GNU General Public License, Version 2, as 
    40 + *  published by the Free Software Foundation. 
    41 + * 
    42 + *  This file is distributed in the hope that it will be useful, 
    43 + *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of 
    44 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 
    45 + *  NONINFRINGEMENT.  See the GNU General Public License for more details. 
    46 + * 
    47 + *  You should have received a copy of the GNU General Public License 
    48 + *  along with this file; if not, write to the Free Software 
    49 + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or 
    50 + *  visit http://www.gnu.org/licenses/. 
    51 + * 
    52 + *  This file may also be available under a different license from Cavium. 
    53 + *  Contact Cavium Networks for more information 
    54 + * 
    55 + ******************************************************************************/ 
    56 + 
    57 +#include <linux/init.h> 
    58 +#include <linux/spinlock.h> 
    59 +#include <linux/workqueue.h> 
    60 +#include <linux/interrupt.h> 
    61 +#include <linux/delay.h> 
    62 +#include <linux/errno.h> 
    63 +#include <linux/err.h> 
    64 +#include <linux/clk.h> 
    65 +#include <linux/platform_device.h> 
    66 + 
    67 +#include <linux/spi/spi.h> 
    68 +#include <linux/spi/spi_bitbang.h> 
    69 +#include <linux/mtd/partitions.h> 
    70 +#include <linux/dma-mapping.h> 
    71 +#include <linux/slab.h> 
    72 + 
    73 +#include <asm/io.h> 
    74 +#include <asm/memory.h> 
    75 +#include <asm/dma.h> 
    76 +#include <asm/delay.h> 
    77 +#include <mach/cns3xxx.h> 
    78 +#include <linux/module.h> 
    79 +#include <mach/pm.h> 
    80 + 
    81 +/* 
    82 + * define access macros 
    83 + */ 
    84 +#define SPI_MEM_MAP_VALUE(reg_offset)          (*((u32 volatile *)(CNS3XXX_SSP_BASE_VIRT + reg_offset))) 
    85 + 
    86 +#define SPI_CONFIGURATION_REG                  SPI_MEM_MAP_VALUE(0x40) 
    87 +#define SPI_SERVICE_STATUS_REG                 SPI_MEM_MAP_VALUE(0x44) 
    88 +#define SPI_BIT_RATE_CONTROL_REG               SPI_MEM_MAP_VALUE(0x48) 
    89 +#define SPI_TRANSMIT_CONTROL_REG               SPI_MEM_MAP_VALUE(0x4C) 
    90 +#define SPI_TRANSMIT_BUFFER_REG                        SPI_MEM_MAP_VALUE(0x50) 
    91 +#define SPI_RECEIVE_CONTROL_REG                        SPI_MEM_MAP_VALUE(0x54) 
    92 +#define SPI_RECEIVE_BUFFER_REG                 SPI_MEM_MAP_VALUE(0x58) 
    93 +#define SPI_FIFO_TRANSMIT_CONFIG_REG           SPI_MEM_MAP_VALUE(0x5C) 
    94 +#define SPI_FIFO_TRANSMIT_CONTROL_REG          SPI_MEM_MAP_VALUE(0x60) 
    95 +#define SPI_FIFO_RECEIVE_CONFIG_REG            SPI_MEM_MAP_VALUE(0x64) 
    96 +#define SPI_INTERRUPT_STATUS_REG               SPI_MEM_MAP_VALUE(0x68) 
    97 +#define SPI_INTERRUPT_ENABLE_REG               SPI_MEM_MAP_VALUE(0x6C) 
    98 + 
    99 +#define SPI_TRANSMIT_BUFFER_REG_ADDR           (CNS3XXX_SSP_BASE +0x50) 
    100 +#define SPI_RECEIVE_BUFFER_REG_ADDR            (CNS3XXX_SSP_BASE +0x58) 
    101 + 
    102 +/* Structure for SPI controller of CNS3XXX SOCs */ 
    103 +struct cns3xxx_spi { 
    104 +       /* bitbang has to be first */ 
    105 +       struct spi_bitbang bitbang; 
    106 +       struct completion done; 
    107 +       wait_queue_head_t wait; 
    108 + 
    109 +       int len; 
    110 +       int count; 
    111 +       int last_in_message_list; 
    112 + 
    113 +       /* data buffers */ 
    114 +       const unsigned char *tx; 
    115 +       unsigned char *rx; 
    116 + 
    117 +       struct spi_master *master; 
    118 +       struct platform_device *pdev; 
    119 +       struct device *dev; 
    120 +}; 
    121 + 
    122 +static inline u8 cns3xxx_spi_bus_idle(void) 
    123 +{ 
    124 +       return ((SPI_SERVICE_STATUS_REG & 0x1) ? 0 : 1); 
    125 +} 
    126 + 
    127 +static inline u8 cns3xxx_spi_tx_buffer_empty(void) 
    128 +{ 
    129 +       return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 3)) ? 1 : 0); 
    130 +} 
    131 + 
    132 +static inline u8 cns3xxx_spi_rx_buffer_full(void) 
    133 +{ 
    134 +       return ((SPI_INTERRUPT_STATUS_REG & (0x1 << 2)) ? 1 : 0); 
    135 +} 
    136 + 
    137 +u8 cns3xxx_spi_tx_rx(u8 tx_channel, u8 tx_eof, u32 tx_data, 
    138 +                           u32 * rx_data) 
    139 +{ 
    140 +       u8 rx_channel; 
    141 +       u8 rx_eof; 
    142 + 
    143 +       while (!cns3xxx_spi_bus_idle()) ;       // do nothing 
    144 + 
    145 +       while (!cns3xxx_spi_tx_buffer_empty()) ;        // do nothing 
    146 + 
    147 +       SPI_TRANSMIT_CONTROL_REG &= ~(0x7); 
    148 +       SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof & 0x1) << 2); 
    149 + 
    150 +       SPI_TRANSMIT_BUFFER_REG = tx_data; 
    151 + 
    152 +       while (!cns3xxx_spi_rx_buffer_full()) ; // do nothing 
    153 + 
    154 +       rx_channel = SPI_RECEIVE_CONTROL_REG & 0x3; 
    155 +       rx_eof = (SPI_RECEIVE_CONTROL_REG & (0x1 << 2)) ? 1 : 0; 
    156 + 
    157 +       *rx_data = SPI_RECEIVE_BUFFER_REG; 
    158 + 
    159 +       if ((tx_channel != rx_channel) || (tx_eof != rx_eof)) { 
    160 +               return 0; 
    161 +       } else { 
    162 +               return 1; 
    163 +       } 
    164 +} 
    165 + 
    166 +u8 cns3xxx_spi_tx(u8 tx_channel, u8 tx_eof, u32 tx_data) 
    167 +{ 
    168 + 
    169 +        while (!cns3xxx_spi_bus_idle()) ;       // do nothing 
    170 + 
    171 +        while (!cns3xxx_spi_tx_buffer_empty()) ;        // do nothing 
    172 + 
    173 +        SPI_TRANSMIT_CONTROL_REG &= ~(0x7); 
    174 +        SPI_TRANSMIT_CONTROL_REG |= (tx_channel & 0x3) | ((tx_eof & 0x1) << 2); 
    175 + 
    176 +        SPI_TRANSMIT_BUFFER_REG = tx_data; 
    177 + 
    178 +        return 1; 
    179 +} 
    180 + 
    181 +static inline struct cns3xxx_spi *to_hw(struct spi_device *sdev) 
    182 +{ 
    183 +       return spi_master_get_devdata(sdev->master); 
    184 +} 
    185 + 
    186 +static int cns3xxx_spi_setup_transfer(struct spi_device *spi, 
    187 +                                     struct spi_transfer *t) 
    188 +{ 
    189 +       return 0; 
    190 +} 
    191 + 
    192 +static void cns3xxx_spi_chipselect(struct spi_device *spi, int value) 
    193 +{ 
    194 +       unsigned int spi_config; 
    195 + 
    196 +       switch (value) { 
    197 +       case BITBANG_CS_INACTIVE: 
    198 +               break; 
    199 + 
    200 +       case BITBANG_CS_ACTIVE: 
    201 +               spi_config = SPI_CONFIGURATION_REG; 
    202 + 
    203 +               if (spi->mode & SPI_CPHA) 
    204 +                       spi_config |= (0x1 << 13); 
    205 +               else 
    206 +                       spi_config &= ~(0x1 << 13); 
    207 + 
    208 +               if (spi->mode & SPI_CPOL) 
    209 +                       spi_config |= (0x1 << 14); 
    210 +               else 
    211 +                       spi_config &= ~(0x1 << 14); 
    212 + 
    213 +               /* write new configration */ 
    214 +               SPI_CONFIGURATION_REG = spi_config; 
    215 + 
    216 +               SPI_TRANSMIT_CONTROL_REG &= ~(0x7); 
    217 +               SPI_TRANSMIT_CONTROL_REG |= (spi->chip_select & 0x3); 
    218 + 
    219 +               break; 
    220 +       } 
    221 +} 
    222 + 
    223 +static int cns3xxx_spi_setup(struct spi_device *spi) 
    224 +{ 
    225 +       if (!spi->bits_per_word) 
    226 +               spi->bits_per_word = 8; 
    227 + 
    228 +       return 0; 
    229 +} 
    230 + 
    231 +static int cns3xxx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) 
    232 +{ 
    233 +       struct cns3xxx_spi *hw = to_hw(spi); 
    234 + 
    235 +       dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", t->tx_buf, t->rx_buf, 
    236 +               t->len); 
    237 + 
    238 +       hw->tx = t->tx_buf; 
    239 +       hw->rx = t->rx_buf; 
    240 +       hw->len = t->len; 
    241 +       hw->count = 0; 
    242 +       hw->last_in_message_list = t->last_in_message_list; 
    243 + 
    244 +       init_completion(&hw->done); 
    245 + 
    246 +       if (hw->tx) { 
    247 +               int i; 
    248 +               u32 rx_data; 
    249 +               for (i = 0; i < (hw->len - 1); i++) { 
    250 +                       dev_dbg(&spi->dev, 
    251 +                               "[SPI_CNS3XXX_DEBUG] hw->tx[%02d]: 0x%02x\n", i, 
    252 +                               hw->tx[i]); 
    253 +                       cns3xxx_spi_tx_rx(spi->chip_select, 0, hw->tx[i], 
    254 +                                         &rx_data); 
    255 +                       if (hw->rx) { 
    256 +                               hw->rx[i] = rx_data; 
    257 +                               dev_dbg(&spi->dev, 
    258 +                                       "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n", 
    259 +                                       i, hw->rx[i]); 
    260 +                       } 
    261 +               } 
    262 + 
    263 +               if (t->last_in_message_list) { 
    264 +                       cns3xxx_spi_tx_rx(spi->chip_select, 1, hw->tx[i], 
    265 +                                         &rx_data); 
    266 +                       if (hw->rx) { 
    267 +                               hw->rx[i] = rx_data; 
    268 +                               dev_dbg(&spi->dev, 
    269 +                                       "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n", 
    270 +                                       i, hw->rx[i]); 
    271 +                       } 
    272 +               } else { 
    273 +                       cns3xxx_spi_tx_rx(spi->chip_select, 0, hw->tx[i], 
    274 +                                         &rx_data); 
    275 +               } 
    276 +               goto done; 
    277 +       } 
    278 + 
    279 +       if (hw->rx) { 
    280 +               int i; 
    281 +               u32 rx_data; 
    282 +               for (i = 0; i < (hw->len - 1); i++) { 
    283 +                       cns3xxx_spi_tx_rx(spi->chip_select, 0, 0xff, &rx_data); 
    284 +                       hw->rx[i] = rx_data; 
    285 +                       dev_dbg(&spi->dev, 
    286 +                               "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n", i, 
    287 +                               hw->rx[i]); 
    288 +               } 
    289 + 
    290 +               if (t->last_in_message_list) { 
    291 +                       cns3xxx_spi_tx_rx(spi->chip_select, 1, 0xff, &rx_data); 
    292 +               } else { 
    293 +                       cns3xxx_spi_tx_rx(spi->chip_select, 0, 0xff, &rx_data); 
    294 +               } 
    295 +               hw->rx[i] = rx_data; 
    296 +               dev_dbg(&spi->dev, "[SPI_CNS3XXX_DEBUG] hw->rx[%02d]: 0x%02x\n", 
    297 +                       i, hw->rx[i]); 
    298 +       } 
    299 +done: 
    300 +       return hw->len; 
    301 +} 
    302 + 
    303 +static void __init cns3xxx_spi_initial(void) 
    304 +{ 
    305 +       u32 __iomem *gpiob = __io(CNS3XXX_MISC_BASE_VIRT + 0x0018); 
    306 +       u32 gpiob_pins = __raw_readl(gpiob); 
    307 + 
    308 +       /* MMC/SD pins share with GPIOA */ 
    309 +       gpiob_pins |= 0xf80; 
    310 +       __raw_writel(gpiob_pins, gpiob); 
    311 + 
    312 +       /* share pin config. */ 
    313 +       //PM_PLL_HM_PD_CTRL_REG &= ~(0x1 << 5); 
    314 +       //HAL_MISC_ENABLE_SPI_PINS(); 
    315 +       cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SPI_PCM_I2C)); 
    316 +       cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SPI_PCM_I2C)); 
    317 + 
    318 +       SPI_CONFIGURATION_REG = (((0x0 & 0x3) << 0) |   /* 8bits shift length */ 
    319 +                                (0x0 << 9) |   /* SPI mode */ 
    320 +                                (0x0 << 10) |  /* disable FIFO */ 
    321 +                                (0x1 << 11) |  /* SPI master mode */ 
    322 +                                (0x0 << 12) |  /* disable SPI loopback mode */ 
    323 +                                (0x1 << 13) |  /* clock phase */ 
    324 +                                (0x1 << 14) |  /* clock polarity */ 
    325 +                                (0x0 << 24) |  /* disable - SPI data swap */ 
    326 +                                (0x1 << 29) |  /* enable - 2IO Read mode */ 
    327 +                                (0x0 << 30) |  /* disable - SPI high speed read for system boot up */ 
    328 +                                (0x0 << 31));  /* disable - SPI */ 
    329 + 
    330 +       /* Set SPI bit rate PCLK/2 */ 
    331 +       SPI_BIT_RATE_CONTROL_REG = 0x1; 
    332 + 
    333 +       /* Set SPI Tx channel 0 */ 
    334 +       SPI_TRANSMIT_CONTROL_REG = 0x0; 
    335 + 
    336 +       /* Set Tx FIFO Threshold, Tx FIFO has 2 words */ 
    337 +       SPI_FIFO_TRANSMIT_CONFIG_REG &= ~(0x03 << 4); 
    338 +       SPI_FIFO_TRANSMIT_CONFIG_REG |= ((0x0 & 0x03) << 4); 
    339 + 
    340 +       /* Set Rx FIFO Threshold, Rx FIFO has 2 words */ 
    341 +       SPI_FIFO_RECEIVE_CONFIG_REG &= ~(0x03 << 4); 
    342 +       SPI_FIFO_RECEIVE_CONFIG_REG |= ((0x0 & 0x03) << 4); 
    343 + 
    344 +       /* Disable all interrupt */ 
    345 +       SPI_INTERRUPT_ENABLE_REG = 0x0; 
    346 + 
    347 +       /* Clear spurious interrupt sources */ 
    348 +       SPI_INTERRUPT_STATUS_REG = (0x0F << 4); 
    349 + 
    350 +       /* Enable SPI */ 
    351 +       SPI_CONFIGURATION_REG |= (0x1 << 31); 
    352 + 
    353 +       return; 
    354 +} 
    355 + 
    356 +static int __devinit cns3xxx_spi_probe(struct platform_device *pdev) 
    357 +{ 
    358 +       struct spi_master *master; 
    359 +       struct cns3xxx_spi *hw; 
    360 +       int err = 0; 
    361 + 
    362 +       printk("%s: setup CNS3XXX SPI Controller\n", __FUNCTION__); 
    363 + 
    364 +       /* Allocate master with space for cns3xxx_spi */ 
    365 +       master = spi_alloc_master(&pdev->dev, sizeof(struct cns3xxx_spi)); 
    366 +       if (master == NULL) { 
    367 +               dev_err(&pdev->dev, "No memory for spi_master\n"); 
    368 +               err = -ENOMEM; 
    369 +               goto err_nomem; 
    370 +       } 
    371 + 
    372 +       hw = spi_master_get_devdata(master); 
    373 +       memset(hw, 0, sizeof(struct cns3xxx_spi)); 
    374 + 
    375 +       hw->master = spi_master_get(master); 
    376 +       hw->dev = &pdev->dev; 
    377 + 
    378 +       platform_set_drvdata(pdev, hw); 
    379 +       init_completion(&hw->done); 
    380 + 
    381 +       /* setup the master state. */ 
    382 + 
    383 +       master->num_chipselect = 4; 
    384 +       master->bus_num = 1; 
    385 + 
    386 +       /* setup the state for the bitbang driver */ 
    387 + 
    388 +       hw->bitbang.master = hw->master; 
    389 +       hw->bitbang.setup_transfer = cns3xxx_spi_setup_transfer; 
    390 +       hw->bitbang.chipselect = cns3xxx_spi_chipselect; 
    391 +       hw->bitbang.txrx_bufs = cns3xxx_spi_txrx; 
    392 +       hw->bitbang.master->setup = cns3xxx_spi_setup; 
    393 + 
    394 +       dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); 
    395 + 
    396 +       /* SPI controller initializations */ 
    397 +       cns3xxx_spi_initial(); 
    398 + 
    399 +       /* register SPI controller */ 
    400 + 
    401 +       err = spi_bitbang_start(&hw->bitbang); 
    402 +       if (err) { 
    403 +               dev_err(&pdev->dev, "Failed to register SPI master\n"); 
    404 +               goto err_register; 
    405 +       } 
    406 + 
    407 +       return 0; 
    408 + 
    409 +err_register: 
    410 +       spi_master_put(hw->master);; 
    411 + 
    412 +err_nomem: 
    413 +       return err; 
    414 +} 
    415 + 
    416 +static int __devexit cns3xxx_spi_remove(struct platform_device *dev) 
    417 +{ 
    418 +       struct cns3xxx_spi *hw = platform_get_drvdata(dev); 
    419 + 
    420 +       platform_set_drvdata(dev, NULL); 
    421 + 
    422 +       spi_unregister_master(hw->master); 
    423 + 
    424 +       spi_master_put(hw->master); 
    425 +       return 0; 
    426 +} 
    427 + 
    428 +#ifdef CONFIG_PM 
    429 + 
    430 +static int cns3xxx_spi_suspend(struct platform_device *pdev, pm_message_t msg) 
    431 +{ 
    432 +       struct cns3xxx_spi *hw = platform_get_drvdata(pdev); 
    433 + 
    434 +       return 0; 
    435 +} 
    436 + 
    437 +static int cns3xxx_spi_resume(struct platform_device *pdev) 
    438 +{ 
    439 +       struct cns3xxx_spi *hw = platform_get_drvdata(pdev); 
    440 + 
    441 +       return 0; 
    442 +} 
    443 + 
    444 +#else 
    445 +#define cns3xxx_spi_suspend    NULL 
    446 +#define cns3xxx_spi_resume     NULL 
    447 +#endif 
    448 + 
    449 +static struct platform_driver cns3xxx_spi_driver = { 
    450 +       .probe          = cns3xxx_spi_probe, 
    451 +       .remove         = __devexit_p(cns3xxx_spi_remove), 
    452 +       .suspend        = cns3xxx_spi_suspend, 
    453 +       .resume         = cns3xxx_spi_resume, 
    454 +       .driver         = { 
    455 +               .name = "cns3xxx_spi", 
    456 +               .owner = THIS_MODULE, 
    457 +       }, 
    458 +}; 
    459 + 
    460 +static int __init cns3xxx_spi_init(void) 
    461 +{ 
    462 +       return platform_driver_register(&cns3xxx_spi_driver); 
    463 +} 
    464 + 
    465 +static void __exit cns3xxx_spi_exit(void) 
    466 +{ 
    467 +       platform_driver_unregister(&cns3xxx_spi_driver); 
    468 +} 
    469 + 
    470 +module_init(cns3xxx_spi_init); 
    471 +module_exit(cns3xxx_spi_exit); 
    472 + 
    473 +MODULE_AUTHOR("Cavium Networks"); 
    474 +MODULE_DESCRIPTION("CNS3XXX SPI Controller Driver"); 
    475 +MODULE_LICENSE("GPL"); 
    476 +MODULE_ALIAS("platform:cns3xxx_spi"); 
    477 + 
    478 +EXPORT_SYMBOL_GPL(cns3xxx_spi_tx_rx); 
    479 --- a/include/linux/spi/spi.h 
    480 +++ b/include/linux/spi/spi.h 
    481 @@ -508,6 +508,13 @@ struct spi_transfer { 
    482         u32             speed_hz; 
    483   
    484         struct list_head transfer_list; 
    485 + 
    486 +#ifdef CONFIG_ARCH_CNS3XXX 
    487 +       unsigned        last_in_message_list; 
    488 +#ifdef CONFIG_SPI_CNS3XXX_2IOREAD 
    489 +       u8              dio_read; 
    490 +#endif 
    491 +#endif 
    492  }; 
    493   
    494  /** 
    49527--- a/drivers/spi/spi-bitbang.c 
    49628+++ b/drivers/spi/spi-bitbang.c 
Note: See TracChangeset for help on using the changeset viewer.