doubao_chat/include_lib/driver/cpu/wl82/asm/spi.h

346 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __SPI_H__
#define __SPI_H__
#include "typedef.h"
#include "generic/ioctl.h"
#define SPI_MAX_SIZE (0x7FFFFFFF - 1)//(2^31 - 1)//由于该宏可能赋值给有符合变量,因此使用2^31 - 1
/*enum spi_mode {
SPI_2WIRE_MODE,
SPI_STD_MODE,
SPI_DUAL_MODE,
SPI_QUAD_MODE,
};*/
#define SPI_MODE_SLAVE BIT(0)
#define SPI_UPDATE_SAMPLE_SAME BIT(1)
#define SPI_SCLK_H_UPH_SMPL BIT(2)//CLK空闲H,上升沿更新数据,下降沿采样数据
#define SPI_SCLK_H_UPL_SMPH BIT(3)//CLK空闲H,下降沿更新数据,上升沿采样数据
#define SPI_SCLK_H_UPH_SMPH BIT(4)//CLK空闲H,上升沿更新数据,上升沿采样数据
#define SPI_SCLK_H_UPL_SMPL BIT(5)//CLK空闲H,下降沿更新数据,下降沿采样数据
#define SPI_SCLK_L_UPH_SMPL BIT(6)//CLK空闲L,上升沿更新数据,下降沿采样数据
#define SPI_SCLK_L_UPL_SMPH BIT(7)//CLK空闲L,下降沿更新数据,上升沿采样数据
#define SPI_SCLK_L_UPH_SMPH BIT(8)//CLK空闲L,上升沿更新数据,上升沿采样数据
#define SPI_SCLK_L_UPL_SMPL BIT(9)//CLK空闲L,下降沿更新数据,下降沿采样数据
#define SPI_UNIDIR_MODE BIT(10) //单向:只用SPI_DO一根线数据传输(一般只用于作为从机接收数据)
#define SPI_BIDIR_MODE BIT(11) //双向:用SPI_DO/DI两根线数据传输
#define SPI_SCLK_PORT_HD BIT(13) //SPI CLK时钟开启强电流强驱
#define IOCTL_SPI_SET_CS _IOW('S', 1, u8)
#define IOCTL_SPI_SEND_BYTE _IOW('S', 2, u8)
#define IOCTL_SPI_SEND_CMD_2BIT_MODE _IOW('S', 3, u32)
#define IOCTL_SPI_GET_BIT_MODE _IOW('S', 4, u32)
#define IOCTL_SPI_READ_BYTE _IOW('S', 5, u8)
#define IOCTL_SPI_SET_CRC _IOW('S', 6, u16)
#define IOCTL_SPI_READ_CRC _IOR('S', 7, u16)
#define IOCTL_SFC_SEND_ADDR _IOW('S', 8, u32)
#define IOCTL_SFC_SWITCH_TO_SPI _IOW('S', 9, u32)
#define IOCTL_SFC_DATA_UPDATE _IOW('S', 10, u32)
#define IOCTL_SFC_DATA_ERASE _IOW('S', 11, u32)
#define IOCTL_SPI_SET_IRQ_CPU_ID _IOW('S', 12, u32)
#define IOCTL_SPI_SET_USER_INFO _IOW('S', 13, u32)
#define IOCTL_SPI_READ_DATA _IOR('S', 13, u32)
#define IOCTL_SPI_FREE_DATA _IOW('S', 14, u32)
#define IOCTL_SPI_SET_CB _IOW('S', 15, u32)
#define IOCTL_SPI_SET_USE_SEM _IOW('S', 16, u32)
#define IOCTL_SPI_SET_IRQ_FUNC _IOW('S', 17, u32)
#define IOCTL_SPI_SET_BIT_MODE _IOW('S', 18, u32)
//SPI同一组多ABC口同时使用时切换口命令,使用示例:ioctl(spi_hdl, IOCTL_SPI_SET_PORT, 0);
#define IOCTL_SPI_SET_PORT _IOW('S', 19, u32)
//非阻塞方式发包
#define IOCTL_SPI_NON_BLOCK _IOW('S', 20, u32)
//休眠前需要调用这个当使用非阻塞方式发包时候
#define IOCTL_SPI_WRITE_NON_BLOCK_FLUSH _IOW('S', 21, u32)
//获取spi配置是否阻塞发送
#define IOCTL_SPI_GET_NON_BLOCK _IOR('S', 22, u32)
#define IOCTL_SPI_SET_THRESHOLD_SEM_WAIT _IOW('S', 23, u32)
struct spi_io {
u8 cs_pin;
u8 di_pin;
u8 do_pin;
u8 clk_pin;
u8 d2_pin;
u8 d3_pin;
};
struct spi_2bit_data {
u32 len;
u8 *buf;
};
struct spi_user {
u8 *buf;
u32 buf_size;
u32 dma_max_cnt;
u32 first_dma_size;
u32 block_size;
};
struct spi_cb {
int (*cb_func)(void *priv, u8 **data, u32 *len);
void *cb_priv;
};
struct spi_block {
volatile u8 *buf;
volatile u32 buf_size;
volatile u32 block_num;
volatile u32 dma_max_cnt;
volatile u32 first_dma_size;
volatile u32 block_size;
volatile u32 dma_size;
volatile u32 wblock;
volatile u32 rblock;
volatile u32 free_size;
volatile u8 start;
};
struct spi_regs {
volatile u32 con;
volatile u8 baud;
volatile u8 reg1[3];
volatile u8 buf;
volatile u8 reg2[3];
volatile u32 adr;
volatile u32 cnt;
};
struct sfc_regs {
volatile u32 con;
volatile u16 baud;
volatile u32 reserved0;
volatile u32 base_addr;
volatile u32 reserved1;
volatile u32 econ;
};
struct spi_platform_data {
u8 port;
u8 mode;
u8 irq;
u32 attr;
u32 clk;
const struct spi_io *io;
volatile struct spi_regs *reg;
void (*init)(const struct spi_platform_data *);
};
struct sfc_spi_platform_data {
u8 mode;
u8 ro_mode;
u32 clk;
const struct spi_io *io;
volatile struct spi_regs *spi_reg;
volatile struct sfc_regs *sfc_reg;
};
struct sfc_spi_data {
u32 addr;
u32 len;
};
#define SPI0_PLATFORM_DATA_BEGIN(spi0_data) \
static const struct spi_io spi0_data##_io[] = { \
{ \
.cs_pin = IO_PORTD_00, \
.di_pin = IO_PORTD_01, \
.do_pin = IO_PORTD_05, \
.clk_pin = IO_PORTD_04, \
.d2_pin = IO_PORTD_02, \
.d3_pin = IO_PORTD_03, \
}, \
{ \
.cs_pin = IO_PORTC_05, \
.di_pin = IO_PORTC_00, \
.do_pin = IO_PORTC_04, \
.clk_pin = IO_PORTC_03, \
.d2_pin = IO_PORTC_01, \
.d3_pin = IO_PORTC_02, \
}, \
}; \
static void spi0_data##_iomc_init(const struct spi_platform_data *pd) \
{ \
JL_IOMAP->CON1 &= ~BIT(1); \
if (pd->port == 'A') { \
JL_IOMAP->CON0 &= ~BIT(5); \
} else { \
JL_IOMAP->CON0 |= BIT(5); \
} \
}\
static const struct spi_platform_data spi0_data = { \
.irq = IRQ_SPI0_IDX, \
.io = spi0_data##_io, \
.init = spi0_data##_iomc_init, \
#define SPI0_PLATFORM_DATA_END() \
.reg = (volatile struct spi_regs *)&JL_SPI0->CON, \
};
#define SFC_SPI_PLATFORM_DATA_BEGIN(sfc_spi0_data) \
static const struct spi_io sfc_spi0_io = { \
.cs_pin = IO_PORTD_00, \
.di_pin = IO_PORTD_01, \
.do_pin = IO_PORTD_05, \
.clk_pin = IO_PORTD_04, \
.d2_pin = IO_PORTD_02, \
.d3_pin = IO_PORTD_03, \
}; \
static const struct sfc_spi_platform_data sfc_spi0_data = { \
#define SFC_SPI_PLATFORM_DATA_END() \
.io = &sfc_spi0_io, \
.spi_reg = (volatile struct spi_regs *)&JL_SPI0->CON, \
.sfc_reg = (volatile struct sfc_regs *)&JL_SFC->CON, \
};
#define SPI1_PLATFORM_DATA_BEGIN(spi1_data) \
static const struct spi_io spi1_data##_io[] = { \
{ \
.cs_pin = -1, \
.di_pin = IO_PORTB_05, \
.do_pin = IO_PORTB_07, \
.clk_pin = IO_PORTB_06, \
.d2_pin = -1, \
.d3_pin = -1, \
}, \
{ \
.cs_pin = -1, \
.di_pin = IO_PORTC_08, \
.do_pin = IO_PORTC_10, \
.clk_pin = IO_PORTC_09, \
.d2_pin = -1, \
.d3_pin = -1, \
}, \
}; \
static void spi1_data##_iomc_init(const struct spi_platform_data *pd) \
{ \
if (pd->port == 'A') { \
JL_IOMAP->CON1 &= ~BIT(4); \
} else { \
JL_IOMAP->CON1 |= BIT(4); \
} \
}\
static const struct spi_platform_data spi1_data = { \
.irq = IRQ_SPI1_IDX, \
.io = spi1_data##_io, \
.init = spi1_data##_iomc_init, \
#define SPI1_PLATFORM_DATA_END() \
.reg = (volatile struct spi_regs *)&JL_SPI1->CON, \
};
#define SPI2_PLATFORM_DATA_BEGIN(spi2_data) \
static const struct spi_io spi2_data##_io[] = { \
{ \
.cs_pin = -1, \
.di_pin = IO_PORTH_02, \
.do_pin = IO_PORTH_01, \
.clk_pin = IO_PORTH_00, \
.d2_pin = -1, \
.d3_pin = -1, \
}, \
{ \
.cs_pin = -1, \
.di_pin = IO_PORTG_15, \
.do_pin = IO_PORT_USB_DMA, \
.clk_pin = IO_PORT_USB_DPA, \
.d2_pin = -1, \
.d3_pin = -1, \
}, \
{ \
.cs_pin = -1, \
.di_pin = IO_PORTA_02, \
.do_pin = IO_PORTA_04, \
.clk_pin = IO_PORTA_03, \
.d2_pin = -1, \
.d3_pin = -1, \
}, \
}; \
static void spi2_data##_iomc_init(const struct spi_platform_data *pd) \
{ \
JL_IOMAP->CON1 &= ~(BIT(16) | BIT(17)); \
if (pd->port == 'B') { \
JL_IOMAP->CON1 |= BIT(16); \
} else if (pd->port == 'C') { \
JL_IOMAP->CON1 |= BIT(17); \
} \
}\
static const struct spi_platform_data spi2_data = { \
.irq = IRQ_SPI2_IDX, \
.io = spi2_data##_io, \
.init = spi2_data##_iomc_init, \
#define SPI2_PLATFORM_DATA_END() \
.reg = (volatile struct spi_regs *)&JL_SPI2->CON, \
};
#define SPI3_PLATFORM_DATA_BEGIN(spi3_data) \
static const struct spi_io spi3_data##_io[] = { \
{ \
.cs_pin = IO_PORTG_04, \
.di_pin = IO_PORTG_05, \
.do_pin = IO_PORTG_07, \
.clk_pin = IO_PORTG_03, \
.d2_pin = IO_PORTG_06, \
.d3_pin = IO_PORTG_02, \
}, \
{ \
.cs_pin = IO_PORTG_11, \
.di_pin = IO_PORTG_12, \
.do_pin = IO_PORTG_14, \
.clk_pin = IO_PORTG_10, \
.d2_pin = IO_PORTG_13, \
.d3_pin = IO_PORTG_09, \
}, \
}; \
static void spi3_data##_iomc_init(const struct spi_platform_data *pd) \
{ \
if (pd->port == 'A') { \
JL_IOMAP->CON0 &= ~BIT(15); \
} else { \
JL_IOMAP->CON0 |= BIT(15); \
} \
}\
static const struct spi_platform_data spi3_data = { \
.irq = IRQ_SPI3_IDX, \
.io = spi3_data##_io, \
.init = spi3_data##_iomc_init, \
#define SPI3_PLATFORM_DATA_END() \
.reg = (volatile struct spi_regs *)&JL_SPI3->CON, \
};
extern const struct device_operations spi_dev_ops;
extern const struct device_operations sfc_spi_dev_ops;
#endif