2016-07-23 12:42:54 +02:00
/*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 2011 , 2012 Cavium , Inc .
*/
# include <linux/platform_device.h>
# include <linux/spi/spi.h>
# include <linux/module.h>
# include <linux/io.h>
# include <linux/of.h>
# include <asm/octeon/octeon.h>
# include "spi-cavium.h"
static int octeon_spi_probe ( struct platform_device * pdev )
{
void __iomem * reg_base ;
2023-07-28 17:32:14 +08:00
struct spi_controller * host ;
2016-07-23 12:42:54 +02:00
struct octeon_spi * p ;
int err = - ENOENT ;
2023-07-28 17:32:14 +08:00
host = spi_alloc_host ( & pdev - > dev , sizeof ( struct octeon_spi ) ) ;
if ( ! host )
2016-07-23 12:42:54 +02:00
return - ENOMEM ;
2023-07-28 17:32:14 +08:00
p = spi_controller_get_devdata ( host ) ;
platform_set_drvdata ( pdev , host ) ;
2016-07-23 12:42:54 +02:00
2019-09-04 21:58:51 +08:00
reg_base = devm_platform_ioremap_resource ( pdev , 0 ) ;
2016-07-23 12:42:54 +02:00
if ( IS_ERR ( reg_base ) ) {
err = PTR_ERR ( reg_base ) ;
goto fail ;
}
p - > register_base = reg_base ;
p - > sys_freq = octeon_get_io_clock_rate ( ) ;
p - > regs . config = 0 ;
p - > regs . status = 0x08 ;
p - > regs . tx = 0x10 ;
p - > regs . data = 0x80 ;
2023-07-28 17:32:14 +08:00
host - > num_chipselect = 4 ;
host - > mode_bits = SPI_CPHA |
2016-07-23 12:42:54 +02:00
SPI_CPOL |
SPI_CS_HIGH |
SPI_LSB_FIRST |
SPI_3WIRE ;
2023-07-28 17:32:14 +08:00
host - > transfer_one_message = octeon_spi_transfer_one_message ;
host - > bits_per_word_mask = SPI_BPW_MASK ( 8 ) ;
host - > max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ ;
2016-07-23 12:42:54 +02:00
2023-07-28 17:32:14 +08:00
host - > dev . of_node = pdev - > dev . of_node ;
err = devm_spi_register_controller ( & pdev - > dev , host ) ;
2016-07-23 12:42:54 +02:00
if ( err ) {
2023-07-28 17:32:14 +08:00
dev_err ( & pdev - > dev , " register host failed: %d \n " , err ) ;
2016-07-23 12:42:54 +02:00
goto fail ;
}
dev_info ( & pdev - > dev , " OCTEON SPI bus driver \n " ) ;
return 0 ;
fail :
2023-07-28 17:32:14 +08:00
spi_controller_put ( host ) ;
2016-07-23 12:42:54 +02:00
return err ;
}
2023-03-03 18:19:31 +01:00
static void octeon_spi_remove ( struct platform_device * pdev )
2016-07-23 12:42:54 +02:00
{
2023-07-28 17:32:14 +08:00
struct spi_controller * host = platform_get_drvdata ( pdev ) ;
struct octeon_spi * p = spi_controller_get_devdata ( host ) ;
2016-07-23 12:42:54 +02:00
/* Clear the CSENA* and put everything in a known state. */
writeq ( 0 , p - > register_base + OCTEON_SPI_CFG ( p ) ) ;
}
static const struct of_device_id octeon_spi_match [ ] = {
{ . compatible = " cavium,octeon-3010-spi " , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , octeon_spi_match ) ;
static struct platform_driver octeon_spi_driver = {
. driver = {
. name = " spi-octeon " ,
. of_match_table = octeon_spi_match ,
} ,
. probe = octeon_spi_probe ,
2023-03-03 18:19:31 +01:00
. remove_new = octeon_spi_remove ,
2016-07-23 12:42:54 +02:00
} ;
module_platform_driver ( octeon_spi_driver ) ;
MODULE_DESCRIPTION ( " Cavium, Inc. OCTEON SPI bus driver " ) ;
MODULE_AUTHOR ( " David Daney " ) ;
MODULE_LICENSE ( " GPL " ) ;