2017-09-15 10:29:16 +03:00
/*
* Copyright ( C ) 2017 Spreadtrum Communications Inc .
*
* SPDX - License - Identifier : GPL - 2.0
*/
2018-03-20 05:42:14 +03:00
# include <linux/delay.h>
2017-09-15 10:29:16 +03:00
# include <linux/hwspinlock.h>
# include <linux/init.h>
# include <linux/io.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/of.h>
# include <linux/platform_device.h>
2018-03-20 05:42:14 +03:00
# include <linux/reboot.h>
2017-09-15 10:29:16 +03:00
# include <linux/spi/spi.h>
# include <linux/sizes.h>
/* Registers definitions for ADI controller */
# define REG_ADI_CTRL0 0x4
# define REG_ADI_CHN_PRIL 0x8
# define REG_ADI_CHN_PRIH 0xc
# define REG_ADI_INT_EN 0x10
# define REG_ADI_INT_RAW 0x14
# define REG_ADI_INT_MASK 0x18
# define REG_ADI_INT_CLR 0x1c
# define REG_ADI_GSSI_CFG0 0x20
# define REG_ADI_GSSI_CFG1 0x24
# define REG_ADI_RD_CMD 0x28
# define REG_ADI_RD_DATA 0x2c
# define REG_ADI_ARM_FIFO_STS 0x30
# define REG_ADI_STS 0x34
# define REG_ADI_EVT_FIFO_STS 0x38
# define REG_ADI_ARM_CMD_STS 0x3c
# define REG_ADI_CHN_EN 0x40
# define REG_ADI_CHN_ADDR(id) (0x44 + (id - 2) * 4)
# define REG_ADI_CHN_EN1 0x20c
/* Bits definitions for register REG_ADI_GSSI_CFG0 */
# define BIT_CLK_ALL_ON BIT(30)
/* Bits definitions for register REG_ADI_RD_DATA */
# define BIT_RD_CMD_BUSY BIT(31)
# define RD_ADDR_SHIFT 16
# define RD_VALUE_MASK GENMASK(15, 0)
# define RD_ADDR_MASK GENMASK(30, 16)
/* Bits definitions for register REG_ADI_ARM_FIFO_STS */
# define BIT_FIFO_FULL BIT(11)
# define BIT_FIFO_EMPTY BIT(10)
/*
* ADI slave devices include RTC , ADC , regulator , charger , thermal and so on .
2021-08-26 12:15:47 +03:00
* ADI supports 12 / 14 bit address for r2p0 , and additional 17 bit for r3p0 or
* later versions . Since bit [ 1 : 0 ] are zero , so the spec describe them as
* 10 / 12 / 15 bit address mode .
* The 10 bit mode supports sigle slave , 12 / 15 bit mode supports 3 slave , the
* high two bits is slave_id .
* The slave devices address offset is 0x8000 for 10 / 12 bit address mode ,
* and 0x20000 for 15 bit mode .
2017-09-15 10:29:16 +03:00
*/
2021-08-26 12:15:47 +03:00
# define ADI_10BIT_SLAVE_ADDR_SIZE SZ_4K
# define ADI_10BIT_SLAVE_OFFSET 0x8000
# define ADI_12BIT_SLAVE_ADDR_SIZE SZ_16K
# define ADI_12BIT_SLAVE_OFFSET 0x8000
# define ADI_15BIT_SLAVE_ADDR_SIZE SZ_128K
# define ADI_15BIT_SLAVE_OFFSET 0x20000
2017-09-15 10:29:16 +03:00
/* Timeout (ms) for the trylock of hardware spinlocks */
# define ADI_HWSPINLOCK_TIMEOUT 5000
/*
* ADI controller has 50 channels including 2 software channels
* and 48 hardware channels .
*/
# define ADI_HW_CHNS 50
# define ADI_FIFO_DRAIN_TIMEOUT 1000
# define ADI_READ_TIMEOUT 2000
2021-08-26 12:15:47 +03:00
/*
* Read back address from REG_ADI_RD_DATA bit [ 30 : 16 ] which maps to :
* REG_ADI_RD_CMD bit [ 14 : 0 ] for r2p0
* REG_ADI_RD_CMD bit [ 16 : 2 ] for r3p0
*/
# define RDBACK_ADDR_MASK_R2 GENMASK(14, 0)
# define RDBACK_ADDR_MASK_R3 GENMASK(16, 2)
# define RDBACK_ADDR_SHIFT_R3 2
2017-09-15 10:29:16 +03:00
2018-03-20 05:42:14 +03:00
/* Registers definitions for PMIC watchdog controller */
2021-08-26 12:15:47 +03:00
# define REG_WDG_LOAD_LOW 0x0
# define REG_WDG_LOAD_HIGH 0x4
# define REG_WDG_CTRL 0x8
# define REG_WDG_LOCK 0x20
2018-03-20 05:42:14 +03:00
/* Bits definitions for register REG_WDG_CTRL */
# define BIT_WDG_RUN BIT(1)
2019-10-28 13:10:31 +03:00
# define BIT_WDG_NEW BIT(2)
2018-03-20 05:42:14 +03:00
# define BIT_WDG_RST BIT(3)
2021-08-26 12:15:47 +03:00
/* Bits definitions for register REG_MODULE_EN */
# define BIT_WDG_EN BIT(2)
2018-03-20 05:42:14 +03:00
/* Registers definitions for PMIC */
# define PMIC_RST_STATUS 0xee8
# define PMIC_MODULE_EN 0xc08
# define PMIC_CLK_EN 0xc18
2021-08-26 12:15:47 +03:00
# define PMIC_WDG_BASE 0x80
2018-03-20 05:42:14 +03:00
/* Definition of PMIC reset status register */
2019-07-26 10:20:49 +03:00
# define HWRST_STATUS_SECURITY 0x02
2018-03-20 05:42:14 +03:00
# define HWRST_STATUS_RECOVERY 0x20
# define HWRST_STATUS_NORMAL 0x40
# define HWRST_STATUS_ALARM 0x50
# define HWRST_STATUS_SLEEP 0x60
# define HWRST_STATUS_FASTBOOT 0x30
# define HWRST_STATUS_SPECIAL 0x70
# define HWRST_STATUS_PANIC 0x80
# define HWRST_STATUS_CFTREBOOT 0x90
# define HWRST_STATUS_AUTODLOADER 0xa0
# define HWRST_STATUS_IQMODE 0xb0
# define HWRST_STATUS_SPRDISK 0xc0
2019-07-26 10:20:50 +03:00
# define HWRST_STATUS_FACTORYTEST 0xe0
2019-07-26 10:20:51 +03:00
# define HWRST_STATUS_WATCHDOG 0xf0
2018-03-20 05:42:14 +03:00
/* Use default timeout 50 ms that converts to watchdog values */
2021-08-26 12:15:46 +03:00
# define WDG_LOAD_VAL ((50 * 32768) / 1000)
2018-03-20 05:42:14 +03:00
# define WDG_LOAD_MASK GENMASK(15, 0)
# define WDG_UNLOCK_KEY 0xe551
2021-08-26 12:15:47 +03:00
struct sprd_adi_wdg {
u32 base ;
u32 rst_sts ;
u32 wdg_en ;
u32 wdg_clk ;
} ;
struct sprd_adi_data {
u32 slave_offset ;
u32 slave_addr_size ;
int ( * read_check ) ( u32 val , u32 reg ) ;
2023-11-17 19:10:05 +03:00
int ( * restart ) ( struct sys_off_data * data ) ;
2021-08-26 12:15:47 +03:00
void ( * wdg_rst ) ( void * p ) ;
} ;
2017-09-15 10:29:16 +03:00
struct sprd_adi {
struct spi_controller * ctlr ;
struct device * dev ;
void __iomem * base ;
struct hwspinlock * hwlock ;
unsigned long slave_vbase ;
unsigned long slave_pbase ;
2021-08-26 12:15:47 +03:00
const struct sprd_adi_data * data ;
2017-09-15 10:29:16 +03:00
} ;
2021-08-24 10:02:10 +03:00
static int sprd_adi_check_addr ( struct sprd_adi * sadi , u32 reg )
2017-09-15 10:29:16 +03:00
{
2021-08-26 12:15:47 +03:00
if ( reg > = sadi - > data - > slave_addr_size ) {
2017-09-15 10:29:16 +03:00
dev_err ( sadi - > dev ,
2021-08-24 10:02:10 +03:00
" slave address offset is incorrect, reg = 0x%x \n " ,
reg ) ;
2017-09-15 10:29:16 +03:00
return - EINVAL ;
}
return 0 ;
}
static int sprd_adi_drain_fifo ( struct sprd_adi * sadi )
{
u32 timeout = ADI_FIFO_DRAIN_TIMEOUT ;
u32 sts ;
do {
sts = readl_relaxed ( sadi - > base + REG_ADI_ARM_FIFO_STS ) ;
if ( sts & BIT_FIFO_EMPTY )
break ;
cpu_relax ( ) ;
} while ( - - timeout ) ;
if ( timeout = = 0 ) {
dev_err ( sadi - > dev , " drain write fifo timeout \n " ) ;
return - EBUSY ;
}
return 0 ;
}
static int sprd_adi_fifo_is_full ( struct sprd_adi * sadi )
{
return readl_relaxed ( sadi - > base + REG_ADI_ARM_FIFO_STS ) & BIT_FIFO_FULL ;
}
2021-08-26 12:15:47 +03:00
static int sprd_adi_read_check ( u32 val , u32 addr )
{
u32 rd_addr ;
rd_addr = ( val & RD_ADDR_MASK ) > > RD_ADDR_SHIFT ;
if ( rd_addr ! = addr ) {
pr_err ( " ADI read error, addr = 0x%x, val = 0x%x \n " , addr , val ) ;
return - EIO ;
}
return 0 ;
}
static int sprd_adi_read_check_r2 ( u32 val , u32 reg )
{
return sprd_adi_read_check ( val , reg & RDBACK_ADDR_MASK_R2 ) ;
}
static int sprd_adi_read_check_r3 ( u32 val , u32 reg )
{
return sprd_adi_read_check ( val , ( reg & RDBACK_ADDR_MASK_R3 ) > > RDBACK_ADDR_SHIFT_R3 ) ;
}
2021-08-24 10:02:10 +03:00
static int sprd_adi_read ( struct sprd_adi * sadi , u32 reg , u32 * read_val )
2017-09-15 10:29:16 +03:00
{
int read_timeout = ADI_READ_TIMEOUT ;
2018-03-20 05:42:13 +03:00
unsigned long flags ;
2021-08-26 12:15:47 +03:00
u32 val ;
2019-07-26 10:20:52 +03:00
int ret = 0 ;
if ( sadi - > hwlock ) {
ret = hwspin_lock_timeout_irqsave ( sadi - > hwlock ,
ADI_HWSPINLOCK_TIMEOUT ,
& flags ) ;
if ( ret ) {
dev_err ( sadi - > dev , " get the hw lock failed \n " ) ;
return ret ;
}
2018-03-20 05:42:13 +03:00
}
2017-09-15 10:29:16 +03:00
2021-08-24 10:02:10 +03:00
ret = sprd_adi_check_addr ( sadi , reg ) ;
if ( ret )
goto out ;
2017-09-15 10:29:16 +03:00
/*
2021-08-24 10:02:12 +03:00
* Set the slave address offset need to read into RD_CMD register ,
2017-09-15 10:29:16 +03:00
* then ADI controller will start to transfer automatically .
*/
2021-08-24 10:02:12 +03:00
writel_relaxed ( reg , sadi - > base + REG_ADI_RD_CMD ) ;
2017-09-15 10:29:16 +03:00
/*
* Wait read operation complete , the BIT_RD_CMD_BUSY will be set
* simultaneously when writing read command to register , and the
* BIT_RD_CMD_BUSY will be cleared after the read operation is
* completed .
*/
do {
val = readl_relaxed ( sadi - > base + REG_ADI_RD_DATA ) ;
if ( ! ( val & BIT_RD_CMD_BUSY ) )
break ;
cpu_relax ( ) ;
} while ( - - read_timeout ) ;
if ( read_timeout = = 0 ) {
dev_err ( sadi - > dev , " ADI read timeout \n " ) ;
2018-03-20 05:42:13 +03:00
ret = - EBUSY ;
goto out ;
2017-09-15 10:29:16 +03:00
}
/*
2021-08-26 12:15:47 +03:00
* The return value before adi r5p0 includes data and read register
* address , from bit 0 to bit 15 are data , and from bit 16 to bit 30
* are read register address . Then we can check the returned register
* address to validate data .
2017-09-15 10:29:16 +03:00
*/
2021-08-26 12:15:47 +03:00
if ( sadi - > data - > read_check ) {
ret = sadi - > data - > read_check ( val , reg ) ;
if ( ret < 0 )
goto out ;
2017-09-15 10:29:16 +03:00
}
* read_val = val & RD_VALUE_MASK ;
2018-03-20 05:42:13 +03:00
out :
2019-07-26 10:20:52 +03:00
if ( sadi - > hwlock )
hwspin_unlock_irqrestore ( sadi - > hwlock , & flags ) ;
2018-03-20 05:42:13 +03:00
return ret ;
2017-09-15 10:29:16 +03:00
}
2021-08-24 10:02:10 +03:00
static int sprd_adi_write ( struct sprd_adi * sadi , u32 reg , u32 val )
2017-09-15 10:29:16 +03:00
{
u32 timeout = ADI_FIFO_DRAIN_TIMEOUT ;
2018-03-20 05:42:13 +03:00
unsigned long flags ;
2017-09-15 10:29:16 +03:00
int ret ;
2019-07-26 10:20:52 +03:00
if ( sadi - > hwlock ) {
ret = hwspin_lock_timeout_irqsave ( sadi - > hwlock ,
ADI_HWSPINLOCK_TIMEOUT ,
& flags ) ;
if ( ret ) {
dev_err ( sadi - > dev , " get the hw lock failed \n " ) ;
return ret ;
}
2018-03-20 05:42:13 +03:00
}
2021-08-24 10:02:10 +03:00
ret = sprd_adi_check_addr ( sadi , reg ) ;
if ( ret )
goto out ;
2017-09-15 10:29:16 +03:00
ret = sprd_adi_drain_fifo ( sadi ) ;
if ( ret < 0 )
2018-03-20 05:42:13 +03:00
goto out ;
2017-09-15 10:29:16 +03:00
/*
* we should wait for write fifo is empty before writing data to PMIC
* registers .
*/
do {
if ( ! sprd_adi_fifo_is_full ( sadi ) ) {
2021-08-24 10:02:10 +03:00
/* we need virtual register address to write. */
writel_relaxed ( val , ( void __iomem * ) ( sadi - > slave_vbase + reg ) ) ;
2017-09-15 10:29:16 +03:00
break ;
}
cpu_relax ( ) ;
} while ( - - timeout ) ;
if ( timeout = = 0 ) {
dev_err ( sadi - > dev , " write fifo is full \n " ) ;
2018-03-20 05:42:13 +03:00
ret = - EBUSY ;
2017-09-15 10:29:16 +03:00
}
2018-03-20 05:42:13 +03:00
out :
2019-07-26 10:20:52 +03:00
if ( sadi - > hwlock )
hwspin_unlock_irqrestore ( sadi - > hwlock , & flags ) ;
2018-03-20 05:42:13 +03:00
return ret ;
2017-09-15 10:29:16 +03:00
}
static int sprd_adi_transfer_one ( struct spi_controller * ctlr ,
struct spi_device * spi_dev ,
struct spi_transfer * t )
{
struct sprd_adi * sadi = spi_controller_get_devdata ( ctlr ) ;
2021-08-24 10:02:10 +03:00
u32 reg , val ;
2017-09-15 10:29:16 +03:00
int ret ;
if ( t - > rx_buf ) {
2021-08-24 10:02:10 +03:00
reg = * ( u32 * ) t - > rx_buf ;
ret = sprd_adi_read ( sadi , reg , & val ) ;
2017-09-15 10:29:16 +03:00
* ( u32 * ) t - > rx_buf = val ;
} else if ( t - > tx_buf ) {
u32 * p = ( u32 * ) t - > tx_buf ;
2021-08-24 10:02:10 +03:00
reg = * p + + ;
2017-09-15 10:29:16 +03:00
val = * p ;
2021-08-24 10:02:10 +03:00
ret = sprd_adi_write ( sadi , reg , val ) ;
2017-09-15 10:29:16 +03:00
} else {
dev_err ( sadi - > dev , " no buffer for transfer \n " ) ;
2021-08-24 10:02:10 +03:00
ret = - EINVAL ;
2017-09-15 10:29:16 +03:00
}
2021-08-24 10:02:10 +03:00
return ret ;
2017-09-15 10:29:16 +03:00
}
2021-08-26 12:15:47 +03:00
static void sprd_adi_set_wdt_rst_mode ( void * p )
2019-07-26 10:20:51 +03:00
{
2020-04-13 09:30:25 +03:00
# if IS_ENABLED(CONFIG_SPRD_WATCHDOG)
2019-07-26 10:20:51 +03:00
u32 val ;
2021-08-26 12:15:47 +03:00
struct sprd_adi * sadi = ( struct sprd_adi * ) p ;
2019-07-26 10:20:51 +03:00
2021-08-26 12:15:47 +03:00
/* Init watchdog reset mode */
2021-08-24 10:02:10 +03:00
sprd_adi_read ( sadi , PMIC_RST_STATUS , & val ) ;
2019-07-26 10:20:51 +03:00
val | = HWRST_STATUS_WATCHDOG ;
2021-08-24 10:02:10 +03:00
sprd_adi_write ( sadi , PMIC_RST_STATUS , val ) ;
2019-07-26 10:20:51 +03:00
# endif
}
2023-11-17 19:10:05 +03:00
static int sprd_adi_restart ( struct sprd_adi * sadi , unsigned long mode ,
const char * cmd , struct sprd_adi_wdg * wdg )
2018-03-20 05:42:14 +03:00
{
u32 val , reboot_mode = 0 ;
if ( ! cmd )
reboot_mode = HWRST_STATUS_NORMAL ;
else if ( ! strncmp ( cmd , " recovery " , 8 ) )
reboot_mode = HWRST_STATUS_RECOVERY ;
else if ( ! strncmp ( cmd , " alarm " , 5 ) )
reboot_mode = HWRST_STATUS_ALARM ;
else if ( ! strncmp ( cmd , " fastsleep " , 9 ) )
reboot_mode = HWRST_STATUS_SLEEP ;
else if ( ! strncmp ( cmd , " bootloader " , 10 ) )
reboot_mode = HWRST_STATUS_FASTBOOT ;
else if ( ! strncmp ( cmd , " panic " , 5 ) )
reboot_mode = HWRST_STATUS_PANIC ;
else if ( ! strncmp ( cmd , " special " , 7 ) )
reboot_mode = HWRST_STATUS_SPECIAL ;
else if ( ! strncmp ( cmd , " cftreboot " , 9 ) )
reboot_mode = HWRST_STATUS_CFTREBOOT ;
else if ( ! strncmp ( cmd , " autodloader " , 11 ) )
reboot_mode = HWRST_STATUS_AUTODLOADER ;
else if ( ! strncmp ( cmd , " iqmode " , 6 ) )
reboot_mode = HWRST_STATUS_IQMODE ;
else if ( ! strncmp ( cmd , " sprdisk " , 7 ) )
reboot_mode = HWRST_STATUS_SPRDISK ;
2019-07-26 10:20:49 +03:00
else if ( ! strncmp ( cmd , " tospanic " , 8 ) )
reboot_mode = HWRST_STATUS_SECURITY ;
2019-07-26 10:20:50 +03:00
else if ( ! strncmp ( cmd , " factorytest " , 11 ) )
reboot_mode = HWRST_STATUS_FACTORYTEST ;
2018-03-20 05:42:14 +03:00
else
reboot_mode = HWRST_STATUS_NORMAL ;
/* Record the reboot mode */
2021-08-26 12:15:47 +03:00
sprd_adi_read ( sadi , wdg - > rst_sts , & val ) ;
2019-07-26 10:20:51 +03:00
val & = ~ HWRST_STATUS_WATCHDOG ;
2018-03-20 05:42:14 +03:00
val | = reboot_mode ;
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > rst_sts , val ) ;
2018-03-20 05:42:14 +03:00
/* Enable the interface clock of the watchdog */
2021-08-26 12:15:47 +03:00
sprd_adi_read ( sadi , wdg - > wdg_en , & val ) ;
2018-03-20 05:42:14 +03:00
val | = BIT_WDG_EN ;
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > wdg_en , val ) ;
2018-03-20 05:42:14 +03:00
/* Enable the work clock of the watchdog */
2021-08-26 12:15:47 +03:00
sprd_adi_read ( sadi , wdg - > wdg_clk , & val ) ;
2018-03-20 05:42:14 +03:00
val | = BIT_WDG_EN ;
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > wdg_clk , val ) ;
2018-03-20 05:42:14 +03:00
/* Unlock the watchdog */
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > base + REG_WDG_LOCK , WDG_UNLOCK_KEY ) ;
2018-03-20 05:42:14 +03:00
2021-08-26 12:15:47 +03:00
sprd_adi_read ( sadi , wdg - > base + REG_WDG_CTRL , & val ) ;
2019-10-28 13:10:31 +03:00
val | = BIT_WDG_NEW ;
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > base + REG_WDG_CTRL , val ) ;
2019-10-28 13:10:31 +03:00
2018-03-20 05:42:14 +03:00
/* Load the watchdog timeout value, 50ms is always enough. */
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > base + REG_WDG_LOAD_HIGH , 0 ) ;
sprd_adi_write ( sadi , wdg - > base + REG_WDG_LOAD_LOW ,
2018-03-20 05:42:14 +03:00
WDG_LOAD_VAL & WDG_LOAD_MASK ) ;
/* Start the watchdog to reset system */
2021-08-26 12:15:47 +03:00
sprd_adi_read ( sadi , wdg - > base + REG_WDG_CTRL , & val ) ;
2018-03-20 05:42:14 +03:00
val | = BIT_WDG_RUN | BIT_WDG_RST ;
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > base + REG_WDG_CTRL , val ) ;
2018-03-20 05:42:14 +03:00
2019-10-28 13:10:30 +03:00
/* Lock the watchdog */
2021-08-26 12:15:47 +03:00
sprd_adi_write ( sadi , wdg - > base + REG_WDG_LOCK , ~ WDG_UNLOCK_KEY ) ;
2019-10-28 13:10:30 +03:00
2018-03-20 05:42:14 +03:00
mdelay ( 1000 ) ;
dev_emerg ( sadi - > dev , " Unable to restart system \n " ) ;
return NOTIFY_DONE ;
}
2023-11-17 19:10:05 +03:00
static int sprd_adi_restart_sc9860 ( struct sys_off_data * data )
2021-08-26 12:15:47 +03:00
{
struct sprd_adi_wdg wdg = {
. base = PMIC_WDG_BASE ,
. rst_sts = PMIC_RST_STATUS ,
. wdg_en = PMIC_MODULE_EN ,
. wdg_clk = PMIC_CLK_EN ,
} ;
2023-11-17 19:10:05 +03:00
return sprd_adi_restart ( data - > cb_data , data - > mode , data - > cmd , & wdg ) ;
2021-08-26 12:15:47 +03:00
}
2017-09-15 10:29:16 +03:00
static void sprd_adi_hw_init ( struct sprd_adi * sadi )
{
struct device_node * np = sadi - > dev - > of_node ;
int i , size , chn_cnt ;
const __be32 * list ;
u32 tmp ;
/* Set all channels as default priority */
writel_relaxed ( 0 , sadi - > base + REG_ADI_CHN_PRIL ) ;
writel_relaxed ( 0 , sadi - > base + REG_ADI_CHN_PRIH ) ;
/* Set clock auto gate mode */
tmp = readl_relaxed ( sadi - > base + REG_ADI_GSSI_CFG0 ) ;
tmp & = ~ BIT_CLK_ALL_ON ;
writel_relaxed ( tmp , sadi - > base + REG_ADI_GSSI_CFG0 ) ;
/* Set hardware channels setting */
list = of_get_property ( np , " sprd,hw-channels " , & size ) ;
2017-09-22 23:48:08 +03:00
if ( ! list | | ! size ) {
2017-09-15 10:29:16 +03:00
dev_info ( sadi - > dev , " no hw channels setting in node \n " ) ;
return ;
}
chn_cnt = size / 8 ;
for ( i = 0 ; i < chn_cnt ; i + + ) {
u32 value ;
u32 chn_id = be32_to_cpu ( * list + + ) ;
u32 chn_config = be32_to_cpu ( * list + + ) ;
/* Channel 0 and 1 are software channels */
if ( chn_id < 2 )
continue ;
writel_relaxed ( chn_config , sadi - > base +
REG_ADI_CHN_ADDR ( chn_id ) ) ;
2017-10-25 14:25:09 +03:00
if ( chn_id < 32 ) {
2017-09-15 10:29:16 +03:00
value = readl_relaxed ( sadi - > base + REG_ADI_CHN_EN ) ;
value | = BIT ( chn_id ) ;
writel_relaxed ( value , sadi - > base + REG_ADI_CHN_EN ) ;
} else if ( chn_id < ADI_HW_CHNS ) {
value = readl_relaxed ( sadi - > base + REG_ADI_CHN_EN1 ) ;
value | = BIT ( chn_id - 32 ) ;
writel_relaxed ( value , sadi - > base + REG_ADI_CHN_EN1 ) ;
}
}
}
static int sprd_adi_probe ( struct platform_device * pdev )
{
struct device_node * np = pdev - > dev . of_node ;
2021-08-26 12:15:47 +03:00
const struct sprd_adi_data * data ;
2017-09-15 10:29:16 +03:00
struct spi_controller * ctlr ;
struct sprd_adi * sadi ;
struct resource * res ;
2021-08-26 12:15:47 +03:00
u16 num_chipselect ;
2017-09-15 10:29:16 +03:00
int ret ;
if ( ! np ) {
dev_err ( & pdev - > dev , " can not find the adi bus node \n " ) ;
return - ENODEV ;
}
2021-08-26 12:15:47 +03:00
data = of_device_get_match_data ( & pdev - > dev ) ;
if ( ! data ) {
dev_err ( & pdev - > dev , " no matching driver data found \n " ) ;
return - EINVAL ;
}
2017-09-15 10:29:16 +03:00
pdev - > id = of_alias_get_id ( np , " spi " ) ;
num_chipselect = of_get_child_count ( np ) ;
2023-11-28 12:30:06 +03:00
ctlr = spi_alloc_host ( & pdev - > dev , sizeof ( struct sprd_adi ) ) ;
2017-09-15 10:29:16 +03:00
if ( ! ctlr )
return - ENOMEM ;
dev_set_drvdata ( & pdev - > dev , ctlr ) ;
sadi = spi_controller_get_devdata ( ctlr ) ;
2023-03-27 09:05:15 +03:00
sadi - > base = devm_platform_get_and_ioremap_resource ( pdev , 0 , & res ) ;
2017-09-25 13:21:33 +03:00
if ( IS_ERR ( sadi - > base ) ) {
ret = PTR_ERR ( sadi - > base ) ;
2017-09-15 10:29:16 +03:00
goto put_ctlr ;
}
2021-08-26 12:15:47 +03:00
sadi - > slave_vbase = ( unsigned long ) sadi - > base +
data - > slave_offset ;
sadi - > slave_pbase = res - > start + data - > slave_offset ;
2017-09-15 10:29:16 +03:00
sadi - > ctlr = ctlr ;
sadi - > dev = & pdev - > dev ;
2021-08-26 12:15:47 +03:00
sadi - > data = data ;
2019-07-26 10:20:52 +03:00
ret = of_hwspin_lock_get_id ( np , 0 ) ;
if ( ret > 0 | | ( IS_ENABLED ( CONFIG_HWSPINLOCK ) & & ret = = 0 ) ) {
sadi - > hwlock =
devm_hwspin_lock_request_specific ( & pdev - > dev , ret ) ;
if ( ! sadi - > hwlock ) {
ret = - ENXIO ;
goto put_ctlr ;
}
} else {
switch ( ret ) {
case - ENOENT :
dev_info ( & pdev - > dev , " no hardware spinlock supplied \n " ) ;
break ;
default :
2020-09-10 19:07:06 +03:00
dev_err_probe ( & pdev - > dev , ret , " failed to find hwlock id \n " ) ;
2019-07-26 10:20:52 +03:00
goto put_ctlr ;
}
2017-09-15 10:29:16 +03:00
}
sprd_adi_hw_init ( sadi ) ;
2021-08-26 12:15:47 +03:00
if ( sadi - > data - > wdg_rst )
sadi - > data - > wdg_rst ( sadi ) ;
2017-09-15 10:29:16 +03:00
ctlr - > dev . of_node = pdev - > dev . of_node ;
ctlr - > bus_num = pdev - > id ;
ctlr - > num_chipselect = num_chipselect ;
2023-07-10 18:49:31 +03:00
ctlr - > flags = SPI_CONTROLLER_HALF_DUPLEX ;
2017-09-15 10:29:16 +03:00
ctlr - > bits_per_word_mask = 0 ;
ctlr - > transfer_one = sprd_adi_transfer_one ;
ret = devm_spi_register_controller ( & pdev - > dev , ctlr ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " failed to register SPI controller \n " ) ;
2018-06-22 11:09:05 +03:00
goto put_ctlr ;
2017-09-15 10:29:16 +03:00
}
2021-08-26 12:15:47 +03:00
if ( sadi - > data - > restart ) {
2023-11-17 19:10:05 +03:00
ret = devm_register_restart_handler ( & pdev - > dev ,
sadi - > data - > restart ,
sadi ) ;
2021-08-26 12:15:47 +03:00
if ( ret ) {
dev_err ( & pdev - > dev , " can not register restart handler \n " ) ;
goto put_ctlr ;
}
2018-03-20 05:42:14 +03:00
}
2017-09-15 10:29:16 +03:00
return 0 ;
put_ctlr :
spi_controller_put ( ctlr ) ;
return ret ;
}
2021-08-26 12:15:47 +03:00
static struct sprd_adi_data sc9860_data = {
. slave_offset = ADI_10BIT_SLAVE_OFFSET ,
. slave_addr_size = ADI_10BIT_SLAVE_ADDR_SIZE ,
. read_check = sprd_adi_read_check_r2 ,
. restart = sprd_adi_restart_sc9860 ,
. wdg_rst = sprd_adi_set_wdt_rst_mode ,
} ;
static struct sprd_adi_data sc9863_data = {
. slave_offset = ADI_12BIT_SLAVE_OFFSET ,
. slave_addr_size = ADI_12BIT_SLAVE_ADDR_SIZE ,
. read_check = sprd_adi_read_check_r3 ,
} ;
static struct sprd_adi_data ums512_data = {
. slave_offset = ADI_15BIT_SLAVE_OFFSET ,
. slave_addr_size = ADI_15BIT_SLAVE_ADDR_SIZE ,
. read_check = sprd_adi_read_check_r3 ,
} ;
2017-09-15 10:29:16 +03:00
static const struct of_device_id sprd_adi_of_match [ ] = {
{
. compatible = " sprd,sc9860-adi " ,
2021-08-26 12:15:47 +03:00
. data = & sc9860_data ,
} ,
{
. compatible = " sprd,sc9863-adi " ,
. data = & sc9863_data ,
} ,
{
. compatible = " sprd,ums512-adi " ,
. data = & ums512_data ,
2017-09-15 10:29:16 +03:00
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , sprd_adi_of_match ) ;
static struct platform_driver sprd_adi_driver = {
. driver = {
. name = " sprd-adi " ,
. of_match_table = sprd_adi_of_match ,
} ,
. probe = sprd_adi_probe ,
} ;
module_platform_driver ( sprd_adi_driver ) ;
MODULE_DESCRIPTION ( " Spreadtrum ADI Controller Driver " ) ;
MODULE_AUTHOR ( " Baolin Wang <Baolin.Wang@spreadtrum.com> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;