mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 18:38:55 +00:00
v1.1.1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
|
||||
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -15,6 +15,10 @@
|
||||
#include <hw_symmetric.h>
|
||||
#include <hw_bignum.h>
|
||||
#include <hal_ce.h>
|
||||
#ifdef AIC_DCE_DRV
|
||||
#include <hal_dce.h>
|
||||
#include <hw_crc.h>
|
||||
#endif
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_MAX_KEY_LEN 32
|
||||
@@ -649,6 +653,66 @@ static const struct hwcrypto_hash_ops hash_ops = {
|
||||
.finish = drv_hash_finish,
|
||||
};
|
||||
|
||||
#ifdef AIC_DCE_DRV
|
||||
#define CRC_32_POLY 0x04C11DB7
|
||||
rt_err_t drv_crc_init(struct rt_hwcrypto_ctx *ctx)
|
||||
{
|
||||
rt_err_t res = RT_EOK;
|
||||
|
||||
res = hal_dce_init();
|
||||
if (res)
|
||||
res = -RT_ERROR;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static rt_uint32_t drv_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in,
|
||||
rt_size_t length)
|
||||
{
|
||||
rt_uint32_t crc_result = 0, ret;
|
||||
|
||||
if (ctx->crc_cfg.poly != CRC_32_POLY) {
|
||||
pr_err("Artinchip hardware crc only support CRC_32_POLY.\n");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->crc_cfg.xorout)
|
||||
hal_dce_crc32_xor_val(ctx->crc_cfg.xorout);
|
||||
if (ctx->crc_cfg.flags)
|
||||
hal_dce_crc32_cfg((ctx->crc_cfg.flags & CRC_FLAG_REFIN), 0,
|
||||
(ctx->crc_cfg.flags & CRC_FLAG_REFIN),
|
||||
(ctx->crc_cfg.flags & CRC_FLAG_REFOUT));
|
||||
|
||||
hal_dce_crc32_start(ctx->crc_cfg.last_val, (u8 *)in, length);
|
||||
ret = hal_dce_crc32_wait();
|
||||
if (!ret) {
|
||||
crc_result = hal_dce_crc32_result();
|
||||
} else {
|
||||
pr_err("\t%s error: time out\n", __func__);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
ctx->crc_cfg.last_val = crc_result;
|
||||
return crc_result;
|
||||
}
|
||||
|
||||
void drv_crc_uninit(struct rt_hwcrypto_ctx *ctx)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->contex) {
|
||||
aicos_free_align(0, ctx->contex);
|
||||
ctx->contex = NULL;
|
||||
}
|
||||
hal_dce_deinit();
|
||||
}
|
||||
|
||||
static const struct hwcrypto_crc_ops crc_ops = {
|
||||
.update = drv_crc_update,
|
||||
};
|
||||
#endif
|
||||
|
||||
static rt_err_t aic_hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
|
||||
{
|
||||
rt_err_t res = RT_EOK;
|
||||
@@ -677,6 +741,12 @@ static rt_err_t aic_hwcrypto_create(struct rt_hwcrypto_ctx *ctx)
|
||||
/* Setup HASH operation */
|
||||
((struct hwcrypto_hash *)ctx)->ops = &hash_ops;
|
||||
break;
|
||||
#ifdef AIC_DCE_DRV
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
drv_crc_init(ctx);
|
||||
((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
res = -RT_ERROR;
|
||||
break;
|
||||
@@ -703,6 +773,11 @@ static void aic_hwcrypto_destroy(struct rt_hwcrypto_ctx *ctx)
|
||||
case HWCRYPTO_TYPE_SHA2:
|
||||
drv_sha_uninit(ctx);
|
||||
break;
|
||||
#ifdef AIC_DCE_DRV
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
drv_crc_uninit(ctx);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -743,7 +818,6 @@ static void aic_hwcrypto_reset(struct rt_hwcrypto_ctx *ctx)
|
||||
break;
|
||||
case HWCRYPTO_TYPE_RC4:
|
||||
case HWCRYPTO_TYPE_RNG:
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
break;
|
||||
case HWCRYPTO_TYPE_BIGNUM:
|
||||
drv_rsa_init(ctx);
|
||||
@@ -754,6 +828,11 @@ static void aic_hwcrypto_reset(struct rt_hwcrypto_ctx *ctx)
|
||||
drv_sha_init(ctx);
|
||||
drv_sha_start(ctx);
|
||||
break;
|
||||
#ifdef AIC_DCE_DRV
|
||||
case HWCRYPTO_TYPE_CRC:
|
||||
drv_crc_init(ctx);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#-----------------------------
|
||||
|
||||
menu "CIR protocol select"
|
||||
depends on AIC_USING_CIR
|
||||
depends on (AIC_USING_CIR || AIC_USING_R_CIR)
|
||||
|
||||
config AIC_CIR_NEC
|
||||
bool "NEC protocol"
|
||||
|
||||
@@ -180,6 +180,15 @@ int rt_hw_aic_cir_init(void)
|
||||
aic_cir_dev.dev.type = RT_Device_Class_Char;
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_R_CIR
|
||||
aic_cir_dev.aic_cir_ctrl.cir_base = R_CIR_BASE;
|
||||
aic_cir_dev.aic_cir_ctrl.irq_num = R_CIR_IRQn;
|
||||
#else
|
||||
aic_cir_dev.aic_cir_ctrl.cir_base = CIR_BASE;
|
||||
aic_cir_dev.aic_cir_ctrl.irq_num = CIR_IRQn;
|
||||
#endif
|
||||
aic_cir_dev.aic_cir_ctrl.clk_idx = CLK_CIR;
|
||||
|
||||
rt_mutex_init(&aic_cir_dev.lock, "cir_mutex", RT_IPC_FLAG_PRIO);
|
||||
rt_device_register(&aic_cir_dev.dev, "cir", 0);
|
||||
LOG_I("ArtInChip CIR device register success\n");
|
||||
|
||||
3
bsp/artinchip/drv/dce/Kconfig
Normal file
3
bsp/artinchip/drv/dce/Kconfig
Normal file
@@ -0,0 +1,3 @@
|
||||
#-----------------------------
|
||||
# devices local parameter
|
||||
#-----------------------------
|
||||
8
bsp/artinchip/drv/dce/drv_dce.c
Normal file
8
bsp/artinchip/drv/dce/drv_dce.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology CO.,LTD. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Chen Junlong <junlong.chen@artinchip.com>
|
||||
*/
|
||||
/* do nothing, dce drv is implemented in ce drv */
|
||||
@@ -225,3 +225,26 @@ endif
|
||||
config AIC_PANEL_SPI_EMULATION
|
||||
bool
|
||||
default n
|
||||
|
||||
config AIC_SCREEN_CROP
|
||||
bool "Enable screen crop"
|
||||
default n
|
||||
help
|
||||
Some LCD screen need to be cropped, the effective area displayed is less
|
||||
than the timing signal.
|
||||
If unsure select "N".
|
||||
|
||||
if AIC_SCREEN_CROP
|
||||
config AIC_SCREEN_CROP_POS_X
|
||||
int "screen crop x position of pixels"
|
||||
default 0
|
||||
config AIC_SCREEN_CROP_POS_Y
|
||||
int "screen crop y position of pixels"
|
||||
default 0
|
||||
config AIC_SCREEN_CROP_WIDTH
|
||||
int "screen crop width"
|
||||
default 0
|
||||
config AIC_SCREEN_CROP_HEIGHT
|
||||
int "screen crop height"
|
||||
default 0
|
||||
endif
|
||||
|
||||
@@ -21,17 +21,42 @@
|
||||
/**
|
||||
* lvds channel output order
|
||||
*
|
||||
* default D3 CK D2 D1 D0
|
||||
* 4 3 2 1 0
|
||||
* link 0 default D3 CK D2 D1 D0
|
||||
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
|
||||
*
|
||||
* link 1 default D3 CK D2 D1 D0
|
||||
* PD16/PD17 PD14/PD15 PD12/PD13 PD10/PD11 PD8/PD9
|
||||
*
|
||||
*
|
||||
* link 0 example:
|
||||
* D2 CK D3 D1 D0
|
||||
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
|
||||
*
|
||||
* AIC_LVDS_LINK0_LANES LVDS_LANES(LVDS_D2, LVDS_CK, LVDS_D3, LVDS_D1, LVDS_D0)
|
||||
* link1 example is the same as link0
|
||||
*/
|
||||
#define AIC_LVDS_LINK0_LANES LVDS_LANES(LVDS_D3, LVDS_CK, LVDS_D2, LVDS_D1, LVDS_D0)
|
||||
#define AIC_LVDS_LINK1_LANES LVDS_LANES(LVDS_D3, LVDS_CK, LVDS_D2, LVDS_D1, LVDS_D0)
|
||||
|
||||
/**
|
||||
* lvds channel polarities
|
||||
*
|
||||
* link 0 default PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
|
||||
* N/P N/P N/P N/P N/P
|
||||
*
|
||||
* link 1 default PD16/PD17 PD14/PD15 PD12/PD13 PD10/PD11 PD8/PD9
|
||||
* N/P N/P N/P N/P N/P
|
||||
*
|
||||
*
|
||||
* link 0 example:
|
||||
* PD26/PD27 PD24/PD25 PD22/PD23 PD20/PD21 PD18/PD19
|
||||
* N/P P/N N/P P/N N/P
|
||||
*
|
||||
* AIC_LVDS_LINK0_POL 0b01010
|
||||
* link1 example is the same as link0
|
||||
*/
|
||||
#define AIC_LVDS_LINK0_POL 0x0
|
||||
#define AIC_LVDS_LINK1_POL 0x0
|
||||
#define AIC_LVDS_LINK0_POL 0b00000
|
||||
#define AIC_LVDS_LINK1_POL 0b00000
|
||||
|
||||
/**
|
||||
* lvds channel phy config
|
||||
@@ -43,13 +68,41 @@
|
||||
* MIPI-DSI options
|
||||
*/
|
||||
|
||||
/* data line assignments */
|
||||
/**
|
||||
* data lane assignments
|
||||
*
|
||||
* default D3 D2 D1 D0
|
||||
* PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
|
||||
*
|
||||
* example D0 D1 D2 D3
|
||||
* PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
|
||||
*
|
||||
* LANE_ASSIGNMENTS 0x0123
|
||||
*/
|
||||
#define LANE_ASSIGNMENTS 0x3210
|
||||
|
||||
/* data line polarities */
|
||||
/**
|
||||
* data lane polarities
|
||||
*
|
||||
* default PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
|
||||
* N/P N/P N/P N/P
|
||||
*
|
||||
* example PD26/PD27 PD24/PD25 PD22/PD23 PD19/PD20
|
||||
* P/N N/P P/N N/P
|
||||
*
|
||||
* LANE_POLARITIES 0b1010
|
||||
*/
|
||||
#define LANE_POLARITIES 0b0000
|
||||
|
||||
/* data clk inverse */
|
||||
/**
|
||||
* data clk inverse
|
||||
*
|
||||
* default PD24/PD25
|
||||
* N/P
|
||||
*
|
||||
* CLK_INVERSE 1 PD24/PD25
|
||||
* P/N
|
||||
*/
|
||||
#define CLK_INVERSE 0
|
||||
|
||||
/* virtual channel id */
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
#define DE_TIMEOUT_MS 100
|
||||
|
||||
static unsigned int vsync_flag = 0;
|
||||
static struct aic_de_comp *g_aic_de_comp;
|
||||
|
||||
static int aic_de_set_gamma_config(struct aicfb_gamma_config *gamma);
|
||||
static int aic_de_set_ccm_config(struct aicfb_ccm_config *ccm);
|
||||
|
||||
static struct aic_de_comp *aic_de_request_drvdata(void)
|
||||
{
|
||||
return g_aic_de_comp;
|
||||
@@ -38,10 +40,8 @@ static irqreturn_t aic_de_handler(int irq, void *ctx)
|
||||
status = de_timing_interrupt_status(comp->regs);
|
||||
de_timing_interrupt_clean_status(comp->regs, status);
|
||||
|
||||
if ((status & TIMING_INIT_V_BLANK_FLAG) && vsync_flag) {
|
||||
vsync_flag = 0;
|
||||
if (status & TIMING_INIT_V_BLANK_FLAG)
|
||||
aicos_wqueue_wakeup(comp->vsync_queue);
|
||||
}
|
||||
|
||||
if (comp->scaler_active & SCALER0_CTRL_ACTIVE) {
|
||||
comp->scaler_active = comp->scaler_active & 0xF;
|
||||
@@ -237,6 +237,9 @@ static int aic_de_timing_enable(void)
|
||||
de_timing_enable_interrupt(comp->regs, true, TIMING_INIT_UNDERFLOW_FLAG);
|
||||
#endif
|
||||
|
||||
aic_de_set_gamma_config(&comp->gamma);
|
||||
aic_de_set_ccm_config(&comp->ccm);
|
||||
|
||||
de_timing_enable(comp->regs, 1);
|
||||
|
||||
aic_de_release_drvdata();
|
||||
@@ -257,7 +260,6 @@ static int aic_de_wait_for_vsync(void)
|
||||
struct aic_de_comp *comp = aic_de_request_drvdata();
|
||||
int ret = 0;
|
||||
|
||||
vsync_flag = 1;
|
||||
ret = aicos_wqueue_wait(comp->vsync_queue, DE_TIMEOUT_MS);
|
||||
if (ret < 0) {
|
||||
hal_log_err("DE wait vsync irq failed, ret: %d\n", ret);
|
||||
|
||||
@@ -208,6 +208,11 @@ int config_ui_layer_rect(struct aic_de_comp *comp,
|
||||
de_ui_layer_enable(comp->regs, 1);
|
||||
}
|
||||
|
||||
#ifdef AIC_SCREEN_CROP
|
||||
x_offset += AIC_SCREEN_CROP_POS_X;
|
||||
y_offset += AIC_SCREEN_CROP_POS_Y;
|
||||
#endif
|
||||
|
||||
de_ui_layer_set_rect(comp->regs, in_w, in_h, x_offset, y_offset,
|
||||
stride0, addr0, layer_data->rect_id);
|
||||
de_ui_layer_rect_enable(comp->regs, layer_data->rect_id, 1);
|
||||
|
||||
@@ -746,6 +746,18 @@ static int de_vi_layer_config_format(struct aic_de_comp *comp,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void de_vi_layer_config_crop_pos(struct aic_de_comp *comp,
|
||||
struct aicfb_layer_data *layer_data)
|
||||
{
|
||||
#ifdef AIC_SCREEN_CROP
|
||||
u32 x_offset = layer_data->pos.x + AIC_SCREEN_CROP_POS_X;
|
||||
u32 y_offset = layer_data->pos.y + AIC_SCREEN_CROP_POS_Y;
|
||||
|
||||
reg_write(comp->regs + VIDEO_LAYER_OFFSET,
|
||||
VIDEO_LAYER_OFFSET_SET(x_offset, y_offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
int config_video_layer(struct aic_de_comp *comp,
|
||||
struct aicfb_layer_data *layer_data)
|
||||
{
|
||||
@@ -766,6 +778,7 @@ int config_video_layer(struct aic_de_comp *comp,
|
||||
}
|
||||
|
||||
de_vi_layer_config_format(comp, format_info, layer_data);
|
||||
de_vi_layer_config_crop_pos(comp, layer_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -688,15 +688,20 @@ static void aicfb_fb_info_setup(struct aicfb_info *fbi)
|
||||
fbi->fb_rotate = 0;
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SCREEN_CROP
|
||||
active_w = AIC_SCREEN_CROP_WIDTH;
|
||||
active_h = AIC_SCREEN_CROP_HEIGHT;
|
||||
#else
|
||||
active_w = fbi->panel->timings->hactive;
|
||||
active_h = fbi->panel->timings->vactive;
|
||||
#endif
|
||||
|
||||
if (fbi->fb_rotate == 90 || fbi->fb_rotate == 270)
|
||||
{
|
||||
active_w = fbi->panel->timings->vactive;
|
||||
active_h = fbi->panel->timings->hactive;
|
||||
}
|
||||
else
|
||||
{
|
||||
active_w = fbi->panel->timings->hactive;
|
||||
active_h = fbi->panel->timings->vactive;
|
||||
u32 tmp = active_w;
|
||||
|
||||
active_w = active_h;
|
||||
active_h = tmp;
|
||||
}
|
||||
|
||||
stride = ALIGN_8B(active_w * bpp / 8);
|
||||
@@ -724,8 +729,8 @@ static void fb_color_block(struct aicfb_info *fbi)
|
||||
};
|
||||
unsigned char *pos = (unsigned char *)fbi->fb_start;
|
||||
|
||||
width = fbi->panel->timings->hactive;
|
||||
height = fbi->panel->timings->vactive;
|
||||
width = fbi->width;
|
||||
height = fbi->height;
|
||||
|
||||
switch (fbi->bits_per_pixel) {
|
||||
#if defined(AICFB_ARGB8888) || defined(AICFB_ABGR8888) || defined(AICFB_XRGB8888)
|
||||
@@ -818,7 +823,6 @@ static void aicfb_update_alpha(struct aicfb_info *fbi)
|
||||
static void aicfb_update_layer(struct aicfb_info *fbi)
|
||||
{
|
||||
struct platform_driver *de = fbi->de;
|
||||
struct aic_panel *panel = fbi->panel;
|
||||
struct aicfb_layer_data layer = {0};
|
||||
|
||||
layer.layer_id = AICFB_LAYER_TYPE_UI;
|
||||
@@ -830,11 +834,10 @@ static void aicfb_update_layer(struct aicfb_info *fbi)
|
||||
switch (fbi->fb_rotate)
|
||||
{
|
||||
case 0:
|
||||
layer.buf.size.width = panel->timings->hactive;
|
||||
layer.buf.size.height = panel->timings->vactive;
|
||||
layer.buf.size.width = fbi->width;
|
||||
layer.buf.size.height = fbi->height;
|
||||
layer.buf.stride[0] = fbi->stride;
|
||||
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start;
|
||||
layer.buf.format = AICFB_FORMAT;
|
||||
break;
|
||||
#ifdef AIC_FB_ROTATE_EN
|
||||
case 90:
|
||||
@@ -843,16 +846,15 @@ static void aicfb_update_layer(struct aicfb_info *fbi)
|
||||
unsigned int stride = ALIGN_8B(fbi->height * fbi->bits_per_pixel / 8);
|
||||
|
||||
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start + fbi->fb_size * AIC_FB_DRAW_BUF_NUM;
|
||||
layer.buf.size.width = panel->timings->hactive;
|
||||
layer.buf.size.height = panel->timings->vactive;
|
||||
layer.buf.size.width = fbi->height;
|
||||
layer.buf.size.height = fbi->width;
|
||||
layer.buf.stride[0] = stride;
|
||||
break;
|
||||
}
|
||||
case 180:
|
||||
pr_info("rotate 180\n");
|
||||
layer.buf.phy_addr[0] = (uintptr_t)fbi->fb_start + fbi->fb_size * AIC_FB_DRAW_BUF_NUM;
|
||||
layer.buf.size.width = panel->timings->hactive;
|
||||
layer.buf.size.height = panel->timings->vactive;
|
||||
layer.buf.size.width = fbi->width;
|
||||
layer.buf.size.height = fbi->height;
|
||||
layer.buf.stride[0] = fbi->stride;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,25 @@
|
||||
# i2c devices local parameter
|
||||
#-----------------------------
|
||||
|
||||
# soft_i2c parameter
|
||||
|
||||
menu "SOFT_I2C Parameter"
|
||||
depends on AIC_USING_SOFT_I2C
|
||||
|
||||
config AIC_SOFT_I2C_SCL_PIN
|
||||
string "SOFT_I2C SCL PIN"
|
||||
default "PD.6"
|
||||
|
||||
config AIC_SOFT_I2C_SDA_PIN
|
||||
string "SOFT_I2C SDA PIN"
|
||||
default "PD.7"
|
||||
|
||||
config AIC_DEV_SOFT_I2C_DELAY_TIME
|
||||
int "Setting SOFT_I2C GPIO Level Change Delay Time(us)"
|
||||
default 5
|
||||
|
||||
endmenu
|
||||
|
||||
# i2c0 parameter
|
||||
|
||||
menu "I2C0 Parameter"
|
||||
|
||||
@@ -117,17 +117,24 @@ struct aic_i2c_bus {
|
||||
struct rt_completion cmd_complete;
|
||||
};
|
||||
|
||||
static struct aic_i2c_bus g_aic_i2c_dev[AIC_I2C_CH_NUM];
|
||||
static struct aic_i2c_bus g_aic_i2c_dev[I2C_MAX_CHAN];
|
||||
|
||||
irqreturn_t aic_i2c_slave_irqhandler(int irq, void * data)
|
||||
{
|
||||
int index = irq - I2C0_IRQn;
|
||||
int i, index = 0;
|
||||
uint32_t intr_stat;
|
||||
uint8_t val;
|
||||
uint8_t fifo_num;
|
||||
struct slave_param parm;
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
|
||||
for (i = 0; i < I2C_MAX_CHAN; i++) {
|
||||
if (irq == g_aic_i2c_dev[i].aic_bus.irq_index) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
intr_stat = hal_i2c_get_raw_interrupt_state(i2c_dev);
|
||||
fifo_num = hal_i2c_get_receive_fifo_num(i2c_dev);
|
||||
@@ -280,10 +287,17 @@ static void aic_i2c_handle_write(struct aic_i2c_ctrl *i2c_dev)
|
||||
|
||||
irqreturn_t aic_i2c_irqhandler(int irq, void * data)
|
||||
{
|
||||
int index = irq - I2C0_IRQn;
|
||||
int i, index = 0;
|
||||
uint32_t status = 0;
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
|
||||
for (i = 0; i < I2C_MAX_CHAN; i++) {
|
||||
if (irq == g_aic_i2c_dev[i].aic_bus.irq_index) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
status = hal_i2c_get_raw_interrupt_state(i2c_dev);
|
||||
/* clear all interrupt flags */
|
||||
@@ -386,7 +400,7 @@ static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
||||
}
|
||||
hal_i2c_module_disable(i2c_dev);
|
||||
|
||||
return (ret < 0) ? ret : num;
|
||||
return (ret < 0) ? 0 : num;
|
||||
}
|
||||
#else
|
||||
static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
||||
|
||||
102
bsp/artinchip/drv/i2c/drv_soft_i2c.c
Normal file
102
bsp/artinchip/drv/i2c/drv_soft_i2c.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: hjh <jiehua.huang@artinchip.com>
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <aic_core.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <drivers/i2c-bit-ops.h>
|
||||
#include "aic_hal_clk.h"
|
||||
#include "aic_common.h"
|
||||
#include "aic_log.h"
|
||||
|
||||
#define AIC_SOFT_I2C_TIMEOUT 1000
|
||||
|
||||
struct aic_soft_i2c_pin {
|
||||
u32 sda_pin;
|
||||
u32 scl_pin;
|
||||
};
|
||||
|
||||
struct aic_soft_i2c_bus {
|
||||
struct rt_i2c_bus_device bus;
|
||||
struct aic_soft_i2c_pin aic_i2c_pin;
|
||||
};
|
||||
|
||||
static struct aic_soft_i2c_bus g_aic_soft_i2c;
|
||||
|
||||
static void aic_soft_i2c_set_sda(void *data, rt_int32_t state)
|
||||
{
|
||||
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.sda_pin, PIN_MODE_OUTPUT);
|
||||
rt_pin_write(g_aic_soft_i2c.aic_i2c_pin.sda_pin, state);
|
||||
}
|
||||
|
||||
static void aic_soft_i2c_set_scl(void *data, rt_int32_t state)
|
||||
{
|
||||
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.scl_pin, PIN_MODE_OUTPUT);
|
||||
rt_pin_write(g_aic_soft_i2c.aic_i2c_pin.scl_pin, state);
|
||||
}
|
||||
|
||||
static rt_int32_t aic_soft_i2c_get_sda(void *data)
|
||||
{
|
||||
rt_int32_t ret;
|
||||
|
||||
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.sda_pin, PIN_MODE_INPUT_PULLUP);
|
||||
ret = rt_pin_read(g_aic_soft_i2c.aic_i2c_pin.sda_pin);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_int32_t aic_soft_i2c_get_scl(void *data)
|
||||
{
|
||||
rt_int32_t ret;
|
||||
|
||||
rt_pin_mode(g_aic_soft_i2c.aic_i2c_pin.scl_pin, PIN_MODE_INPUT_PULLUP);
|
||||
ret = rt_pin_read(g_aic_soft_i2c.aic_i2c_pin.scl_pin);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aic_soft_i2c_udelay(rt_uint32_t us)
|
||||
{
|
||||
aic_udelay(us);
|
||||
}
|
||||
|
||||
struct rt_i2c_bit_ops aic_soft_i2c_ops = {
|
||||
.data = NULL,
|
||||
.set_sda = aic_soft_i2c_set_sda,
|
||||
.set_scl = aic_soft_i2c_set_scl,
|
||||
.get_sda = aic_soft_i2c_get_sda,
|
||||
.get_scl = aic_soft_i2c_get_scl,
|
||||
.udelay = aic_soft_i2c_udelay,
|
||||
#ifdef AIC_USING_SOFT_I2C
|
||||
.delay_us = AIC_DEV_SOFT_I2C_DELAY_TIME,
|
||||
#endif
|
||||
.timeout = AIC_SOFT_I2C_TIMEOUT,
|
||||
};
|
||||
|
||||
static int aic_soft_i2c_register()
|
||||
{
|
||||
int ret = RT_EOK;
|
||||
|
||||
#ifdef AIC_USING_SOFT_I2C
|
||||
g_aic_soft_i2c.aic_i2c_pin.sda_pin = rt_pin_get(AIC_SOFT_I2C_SDA_PIN);
|
||||
g_aic_soft_i2c.aic_i2c_pin.scl_pin = rt_pin_get(AIC_SOFT_I2C_SCL_PIN);
|
||||
|
||||
g_aic_soft_i2c.bus.priv = &aic_soft_i2c_ops;
|
||||
|
||||
ret = rt_i2c_bit_add_bus(&g_aic_soft_i2c.bus, "soft_i2c");
|
||||
if (ret) {
|
||||
hal_log_err("register soft i2c fail\r\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
INIT_DEVICE_EXPORT(aic_soft_i2c_register);
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
|
||||
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: Li Siyao <siyao.li@artinchip.com>
|
||||
* Authors: Siyao Li <siyao.li@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
@@ -229,9 +229,16 @@ static rt_uint8_t drv_psadc_resolution(struct rt_adc_device *dev)
|
||||
return 12;
|
||||
}
|
||||
|
||||
static rt_err_t drv_psadc_convert(struct rt_adc_device *dev, rt_uint32_t ch,
|
||||
rt_uint32_t *value)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_adc_ops aic_adc_ops =
|
||||
{
|
||||
.enabled = drv_psadc_enabled,
|
||||
.convert = drv_psadc_convert,
|
||||
.get_resolution = drv_psadc_resolution,
|
||||
.get_adc_values_poll = drv_psadc_get_adc_values_poll,
|
||||
.get_adc_values = drv_psadc_get_adc_values,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Artinchip Technology Co., Ltd
|
||||
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ static struct aic_qspi qspi_controller[] = {
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI1)
|
||||
#if defined(AIC_USING_QSPI1) && !defined(AIC_QSPI1_BUS_SPI)
|
||||
{
|
||||
.name = "qspi1",
|
||||
.idx = 1,
|
||||
@@ -75,7 +75,7 @@ static struct aic_qspi qspi_controller[] = {
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI2)
|
||||
#if defined(AIC_USING_QSPI2) && !defined(AIC_QSPI2_BUS_SPI)
|
||||
{
|
||||
.name = "qspi2",
|
||||
.idx = 2,
|
||||
@@ -93,7 +93,7 @@ static struct aic_qspi qspi_controller[] = {
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI3)
|
||||
#if defined(AIC_USING_QSPI3) && !defined(AIC_QSPI3_BUS_SPI)
|
||||
{
|
||||
.name = "qspi3",
|
||||
.idx = 3,
|
||||
@@ -111,7 +111,7 @@ static struct aic_qspi qspi_controller[] = {
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI4)
|
||||
#if defined(AIC_USING_QSPI4) && !defined(AIC_QSPI4_BUS_SPI)
|
||||
{
|
||||
.name = "qspi4",
|
||||
.idx = 4,
|
||||
|
||||
455
bsp/artinchip/drv/spi/drv_spi.c
Normal file
455
bsp/artinchip/drv/spi/drv_spi.c
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* Copyright (c) 2024, ArtInChip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Authors: Jiji Chen <jiji.chen@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <string.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_drv.h>
|
||||
#include <aic_hal.h>
|
||||
#include <hal_qspi.h>
|
||||
#include <hal_dma.h>
|
||||
#include <aic_dma_id.h>
|
||||
#include <aic_clk_id.h>
|
||||
|
||||
#define ASYNC_DATA_SIZE 64
|
||||
|
||||
struct aic_qspi {
|
||||
struct rt_spi_bus dev;
|
||||
char *name;
|
||||
uint32_t idx;
|
||||
uint32_t clk_id;
|
||||
uint32_t clk_in_hz;
|
||||
uint32_t dma_port_id;
|
||||
uint32_t irq_num;
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
uint32_t cs_num;
|
||||
#endif
|
||||
qspi_master_handle handle;
|
||||
struct rt_qspi_configuration configuration;
|
||||
rt_sem_t xfer_sem;
|
||||
bool inited;
|
||||
uint32_t rxd_dlymode;
|
||||
uint32_t txd_dlymode;
|
||||
uint32_t txc_dlymode;
|
||||
bool nonblock;
|
||||
};
|
||||
|
||||
static struct aic_qspi spi_controller[] = {
|
||||
#if defined(AIC_USING_QSPI1) && defined(AIC_QSPI1_BUS_SPI)
|
||||
{
|
||||
.name = "spi1",
|
||||
.idx = 1,
|
||||
.clk_id = CLK_QSPI1,
|
||||
.clk_in_hz = AIC_DEV_QSPI1_MAX_SRC_FREQ_HZ,
|
||||
.dma_port_id = DMA_ID_SPI1,
|
||||
.irq_num = QSPI1_IRQn,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI1_CS_NUM,
|
||||
#endif
|
||||
.rxd_dlymode = AIC_DEV_QSPI1_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dlymode = AIC_DEV_QSPI1_TXD_DELAY_MODE,
|
||||
.txc_dlymode = AIC_DEV_QSPI1_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI2) && defined(AIC_QSPI2_BUS_SPI)
|
||||
{
|
||||
.name = "spi2",
|
||||
.idx = 2,
|
||||
.clk_id = CLK_QSPI2,
|
||||
.clk_in_hz = AIC_DEV_QSPI2_MAX_SRC_FREQ_HZ,
|
||||
.dma_port_id = DMA_ID_SPI2,
|
||||
.irq_num = QSPI2_IRQn,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI2_CS_NUM,
|
||||
#endif
|
||||
.rxd_dlymode = AIC_DEV_QSPI2_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dlymode = AIC_DEV_QSPI2_TXD_DELAY_MODE,
|
||||
.txc_dlymode = AIC_DEV_QSPI2_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI3) && defined(AIC_QSPI3_BUS_SPI)
|
||||
{
|
||||
.name = "spi3",
|
||||
.idx = 3,
|
||||
.clk_id = CLK_QSPI3,
|
||||
.clk_in_hz = AIC_DEV_QSPI3_MAX_SRC_FREQ_HZ,
|
||||
.dma_port_id = DMA_ID_SPI3,
|
||||
.irq_num = QSPI3_IRQn,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI3_CS_NUM,
|
||||
#endif
|
||||
.rxd_dlymode = AIC_DEV_QSPI3_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dlymode = AIC_DEV_QSPI3_TXD_DELAY_MODE,
|
||||
.txc_dlymode = AIC_DEV_QSPI3_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#if defined(AIC_USING_QSPI4) && defined(AIC_QSPI4_BUS_SPI)
|
||||
{
|
||||
.name = "spi4",
|
||||
.idx = 4,
|
||||
.clk_id = CLK_QSPI4,
|
||||
.clk_in_hz = AIC_DEV_QSPI4_MAX_SRC_FREQ_HZ,
|
||||
.dma_port_id = DMA_ID_SPI4,
|
||||
.irq_num = QSPI4_IRQn,
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
.cs_num = AIC_QSPI4_CS_NUM,
|
||||
#endif
|
||||
.rxd_dlymode = AIC_DEV_QSPI4_DELAY_MODE,
|
||||
#if defined(AIC_QSPI_DRV_V20)
|
||||
.txd_dlymode = AIC_DEV_QSPI4_TXD_DELAY_MODE,
|
||||
.txc_dlymode = AIC_DEV_QSPI4_TX_CLK_DELAY_MODE,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static const u32 bit_mode_table[] = {
|
||||
#ifdef AIC_QSPI1_BIT_MODE
|
||||
1,
|
||||
#endif
|
||||
#ifdef AIC_QSPI2_BIT_MODE
|
||||
2,
|
||||
#endif
|
||||
#ifdef AIC_QSPI3_BIT_MODE
|
||||
3,
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool spi_support_bit_mode(struct aic_qspi *qspi)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < ARRAY_SIZE(bit_mode_table); i++) {
|
||||
if (bit_mode_table[i] == qspi->idx)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef AIC_QSPI_DRV_DEBUG
|
||||
void dump_cmd(uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
printf("CMD: (%lu) ", (unsigned long)len);
|
||||
for (i = 0; i < len; i++)
|
||||
printf("%02X ", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static rt_uint32_t drv_spi_send(struct aic_qspi *qspi,
|
||||
struct rt_spi_message *message,
|
||||
const uint8_t *tx, uint32_t size)
|
||||
{
|
||||
struct qspi_transfer t;
|
||||
u32 ret = 0;
|
||||
|
||||
t.rx_data = NULL;
|
||||
t.tx_data = (uint8_t *)tx;
|
||||
t.data_len = size;
|
||||
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_uint32_t drv_spi_receive(struct aic_qspi *qspi,
|
||||
struct rt_spi_message *message,
|
||||
const uint8_t *tx, uint32_t size)
|
||||
{
|
||||
struct qspi_transfer t;
|
||||
u32 ret = 0;
|
||||
|
||||
t.tx_data = NULL;
|
||||
t.rx_data = (uint8_t *)tx;
|
||||
t.data_len = size;
|
||||
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_uint32_t drv_spi_transfer(struct aic_qspi *qspi,
|
||||
struct rt_spi_message *message)
|
||||
{
|
||||
u32 ret = 0;
|
||||
struct qspi_transfer t;
|
||||
|
||||
t.tx_data = (u8 *)message->send_buf;
|
||||
t.rx_data = message->recv_buf;
|
||||
t.data_len = message->length;
|
||||
ret = hal_qspi_master_transfer_sync(&qspi->handle, &t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spi_set_cs_before(struct rt_spi_device *device,
|
||||
struct rt_spi_message *message)
|
||||
{
|
||||
struct rt_qspi_configuration *cfg;
|
||||
struct aic_qspi *qspi;
|
||||
u32 cs_num = 0;
|
||||
|
||||
qspi = (struct aic_qspi *)device->bus;
|
||||
cfg = &qspi->configuration;
|
||||
|
||||
if (message->cs_take && !(cfg->parent.mode & RT_SPI_NO_CS)) {
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
cs_num = qspi->cs_num;
|
||||
#endif
|
||||
hal_qspi_master_set_cs(&qspi->handle, cs_num, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_set_cs_after(struct rt_spi_device *device,
|
||||
struct rt_spi_message *message)
|
||||
{
|
||||
struct rt_qspi_configuration *cfg;
|
||||
struct aic_qspi *qspi;
|
||||
u32 cs_num = 0;
|
||||
|
||||
qspi = (struct aic_qspi *)device->bus;
|
||||
cfg = &qspi->configuration;
|
||||
|
||||
if (message->cs_release && !(cfg->parent.mode & RT_SPI_NO_CS)) {
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
cs_num = qspi->cs_num;
|
||||
#endif
|
||||
if (!qspi->nonblock)
|
||||
hal_qspi_master_set_cs(&qspi->handle, cs_num, false);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_uint32_t spi_xfer(struct rt_spi_device *device,
|
||||
struct rt_spi_message *message)
|
||||
{
|
||||
struct aic_qspi *qspi;
|
||||
rt_uint32_t ret = 0;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(device->bus != RT_NULL);
|
||||
|
||||
qspi = (struct aic_qspi *)device->bus;
|
||||
|
||||
spi_set_cs_before(device, message);
|
||||
|
||||
if (message->recv_buf && message->send_buf)
|
||||
ret = drv_spi_transfer(qspi, message);
|
||||
else if (message->recv_buf)
|
||||
ret = drv_spi_receive(qspi, message, message->recv_buf, message->length);
|
||||
else if (message->send_buf)
|
||||
ret = drv_spi_send(qspi, message, message->send_buf, message->length);
|
||||
|
||||
spi_set_cs_after(device, message);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
return message->length;
|
||||
}
|
||||
|
||||
static void qspi_master_async_callback(qspi_master_handle *h, void *priv)
|
||||
{
|
||||
struct aic_qspi *qspi = priv;
|
||||
u32 cs_num = 0;
|
||||
|
||||
#if defined(AIC_QSPI_MULTIPLE_CS_NUM)
|
||||
cs_num = qspi->cs_num;
|
||||
#endif
|
||||
rt_sem_release(qspi->xfer_sem);
|
||||
hal_qspi_master_set_cs(&qspi->handle, cs_num, false);
|
||||
}
|
||||
|
||||
static irqreturn_t qspi_irq_handler(int irq_num, void *arg)
|
||||
{
|
||||
qspi_master_handle *h = arg;
|
||||
|
||||
rt_interrupt_enter();
|
||||
hal_qspi_master_irq_handler(h);
|
||||
rt_interrupt_leave();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static rt_err_t spi_configure(struct rt_spi_device *device,
|
||||
struct rt_spi_configuration *configuration)
|
||||
{
|
||||
struct qspi_master_config cfg;
|
||||
struct aic_qspi *qspi;
|
||||
rt_uint32_t bus_hz;
|
||||
rt_err_t ret = RT_EOK;
|
||||
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
RT_ASSERT(configuration != RT_NULL);
|
||||
|
||||
qspi = (struct aic_qspi *)device->bus;
|
||||
|
||||
if (spi_support_bit_mode(qspi))
|
||||
qspi->handle.bit_mode = true;
|
||||
else
|
||||
qspi->handle.bit_mode = false;
|
||||
|
||||
if ((rt_memcmp(&qspi->configuration, configuration,
|
||||
sizeof(struct rt_spi_configuration)) != 0) ||
|
||||
(qspi->handle.bit_mode == true)) {
|
||||
rt_memcpy(&qspi->configuration, configuration,
|
||||
sizeof(struct rt_spi_configuration));
|
||||
rt_memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.idx = qspi->idx;
|
||||
cfg.clk_id = qspi->clk_id;
|
||||
|
||||
bus_hz = configuration->max_hz;
|
||||
if (bus_hz < HAL_QSPI_MIN_FREQ_HZ)
|
||||
bus_hz = HAL_QSPI_MIN_FREQ_HZ;
|
||||
if (bus_hz > HAL_QSPI_MAX_FREQ_HZ)
|
||||
bus_hz = HAL_QSPI_MAX_FREQ_HZ;
|
||||
cfg.clk_in_hz = qspi->clk_in_hz;
|
||||
if (cfg.clk_in_hz > HAL_QSPI_MAX_FREQ_HZ)
|
||||
cfg.clk_in_hz = HAL_QSPI_MAX_FREQ_HZ;
|
||||
if (qspi->clk_in_hz % bus_hz)
|
||||
cfg.clk_in_hz = bus_hz;
|
||||
if (cfg.clk_in_hz < HAL_QSPI_INPUT_MIN_FREQ_HZ)
|
||||
cfg.clk_in_hz = HAL_QSPI_INPUT_MIN_FREQ_HZ;
|
||||
|
||||
if (configuration->mode & RT_SPI_MSB)
|
||||
cfg.lsb_en = false;
|
||||
else
|
||||
cfg.lsb_en = true;
|
||||
if (configuration->mode & RT_SPI_CPHA)
|
||||
cfg.cpha = HAL_QSPI_CPHA_SECOND_EDGE;
|
||||
else
|
||||
cfg.cpha = HAL_QSPI_CPHA_FIRST_EDGE;
|
||||
|
||||
if (configuration->mode & RT_SPI_CPOL)
|
||||
cfg.cpol = HAL_QSPI_CPOL_ACTIVE_LOW;
|
||||
else
|
||||
cfg.cpol = HAL_QSPI_CPOL_ACTIVE_HIGH;
|
||||
if (configuration->mode & RT_SPI_CS_HIGH)
|
||||
cfg.cs_polarity = HAL_QSPI_CS_POL_VALID_HIGH;
|
||||
else
|
||||
cfg.cs_polarity = HAL_QSPI_CS_POL_VALID_LOW;
|
||||
cfg.rx_dlymode = qspi->rxd_dlymode;
|
||||
cfg.tx_dlymode = aic_convert_tx_dlymode(qspi->txc_dlymode, qspi->txd_dlymode);
|
||||
|
||||
ret = hal_qspi_master_init(&qspi->handle, &cfg);
|
||||
if (ret) {
|
||||
pr_err("spi init failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!qspi->inited) {
|
||||
#ifdef AIC_DMA_DRV
|
||||
struct qspi_master_dma_config dmacfg;
|
||||
rt_memset(&dmacfg, 0, sizeof(dmacfg));
|
||||
dmacfg.port_id = qspi->dma_port_id;
|
||||
|
||||
ret = hal_qspi_master_dma_config(&qspi->handle, &dmacfg);
|
||||
if (ret) {
|
||||
pr_err("qspi dma config failed.\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
ret = hal_qspi_master_register_cb(&qspi->handle,
|
||||
qspi_master_async_callback, qspi);
|
||||
if (ret) {
|
||||
pr_err("qspi register async callback failed.\n");
|
||||
return ret;
|
||||
}
|
||||
aicos_request_irq(qspi->irq_num, qspi_irq_handler, 0, NULL,
|
||||
(void *)&qspi->handle);
|
||||
aicos_irq_enable(qspi->irq_num);
|
||||
}
|
||||
bus_hz = configuration->max_hz;
|
||||
if (bus_hz > HAL_QSPI_MAX_FREQ_HZ)
|
||||
bus_hz = HAL_QSPI_MAX_FREQ_HZ;
|
||||
hal_qspi_master_set_bus_freq(&qspi->handle, bus_hz);
|
||||
if (ret) {
|
||||
pr_err("qspi set bus frequency failed.\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
qspi->inited = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_err_t spi_nonblock_set(struct rt_spi_device *device,
|
||||
rt_uint32_t nonblock)
|
||||
{
|
||||
struct aic_qspi *qspi;
|
||||
|
||||
qspi = (struct aic_qspi *)device->bus;
|
||||
if (nonblock == 1)
|
||||
qspi->nonblock = true;
|
||||
else
|
||||
qspi->nonblock = false;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_uint32_t spi_get_transfer_status(struct rt_spi_device *device)
|
||||
{
|
||||
struct aic_qspi *qspi;
|
||||
|
||||
qspi = (struct aic_qspi *)device->bus;
|
||||
|
||||
return hal_qspi_master_get_status(&qspi->handle);
|
||||
}
|
||||
|
||||
rt_err_t aic_spi_bus_attach_device(const char *bus_name,
|
||||
const char *device_name)
|
||||
{
|
||||
struct rt_spi_device *spi_device = RT_NULL;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
RT_ASSERT(bus_name != RT_NULL);
|
||||
RT_ASSERT(device_name != RT_NULL);
|
||||
|
||||
spi_device =
|
||||
(struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
|
||||
|
||||
result = rt_spi_bus_attach_device(spi_device, device_name,
|
||||
bus_name, RT_NULL);
|
||||
|
||||
if (result != RT_EOK && spi_device != NULL)
|
||||
rt_free(spi_device);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct rt_spi_ops aic_spi_ops = {
|
||||
.configure = spi_configure,
|
||||
.xfer = spi_xfer,
|
||||
.nonblock = spi_nonblock_set,
|
||||
.gstatus = spi_get_transfer_status,
|
||||
};
|
||||
|
||||
static int rt_hw_spi_bus_init(void)
|
||||
{
|
||||
char sem_name[RT_NAME_MAX];
|
||||
rt_err_t ret = RT_EOK;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spi_controller); i++) {
|
||||
ret = rt_spi_bus_register(&spi_controller[i].dev,
|
||||
spi_controller[i].name, &aic_spi_ops);
|
||||
if (ret != RT_EOK)
|
||||
break;
|
||||
rt_sprintf(sem_name, "%s_s", spi_controller[i].name);
|
||||
spi_controller[i].xfer_sem =
|
||||
rt_sem_create(sem_name, 0, RT_IPC_FLAG_PRIO);
|
||||
if (!spi_controller[i].xfer_sem) {
|
||||
ret = RT_ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
INIT_BOARD_EXPORT(rt_hw_spi_bus_init);
|
||||
@@ -94,6 +94,10 @@ menu "UART0 Parameter"
|
||||
default 6 if AIC_DEV_UART0_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART0_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART0_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART0_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART0_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART0_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
@@ -258,6 +262,10 @@ menu "UART1 Parameter"
|
||||
default 6 if AIC_DEV_UART1_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART1_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART1_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART1_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART1_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART1_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
@@ -422,6 +430,9 @@ menu "UART2 Parameter"
|
||||
default 6 if AIC_DEV_UART2_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART2_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART2_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART2_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART2_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART2_RTS_ENABLE
|
||||
bool
|
||||
@@ -588,6 +599,10 @@ menu "UART3 Parameter"
|
||||
default 6 if AIC_DEV_UART3_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART3_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART3_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART3_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART3_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART3_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
@@ -752,6 +767,10 @@ menu "UART4 Parameter"
|
||||
default 6 if AIC_DEV_UART4_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART4_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART4_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART4_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART4_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART4_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
@@ -917,6 +936,10 @@ menu "UART5 Parameter"
|
||||
default 6 if AIC_DEV_UART5_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART5_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART5_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART5_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART5_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART5_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
@@ -1081,6 +1104,10 @@ menu "UART6 Parameter"
|
||||
default 6 if AIC_DEV_UART6_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART6_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART6_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART6_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART6_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART6_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
@@ -1245,6 +1272,10 @@ menu "UART7 Parameter"
|
||||
default 6 if AIC_DEV_UART7_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
default 7 if AIC_DEV_UART7_MODE_RS485_SIMULATION
|
||||
|
||||
config AIC_SERIAL_USING_FLOWCTRL
|
||||
bool
|
||||
default y if AIC_DEV_UART7_MODE_RS232_UNAUTO_FLOW_CTRL || AIC_DEV_UART7_MODE_RS232_SW_FLOW_CTRL || AIC_DEV_UART7_MODE_RS232_SW_HW_FLOW_CTRL
|
||||
|
||||
menuconfig AIC_UART7_RTS_ENABLE
|
||||
bool
|
||||
prompt "Enable RTS"
|
||||
|
||||
Reference in New Issue
Block a user