需求:
在新的平台上点亮一款新的RGB屏.写一个通用的spi驱动代码,以后也可以直接使用.
如果使用linux4.4,这可以直接在dts上面配置即可.本文主要记录下spi的通用驱动.
代码
kernel层代码,修改相关的comm和val即可.
如果使用的rk312x平台可以直接移植,如果使用的别的平台,需要修改相关的gpio控制函数.
dts的配置
spidev {
compatible = "spi_st7701s";
cs-gpio = <&gpio3 GPIO_D2 GPIO_ACTIVE_HIGH>;
clk-gpio = <&gpio1 GPIO_B2 GPIO_ACTIVE_HIGH>;
data-gpio = <&gpio1 GPIO_B3 GPIO_ACTIVE_HIGH>;
reset-gpio = <&gpio0 GPIO_D0 GPIO_ACTIVE_HIGH>;
status = "okay";
};
kernel的驱动程序
#include "spi-st7701s.h"
#define __set_st7701s_gpio(np, state) \
__rk_gpio_direction_output(np, state);
static struct spi_data *spi_st7701s_data;
#if 0
{
.comm = 0xFF,
.val = { 0xFF, 0x98, 0x06, 0xFF }
},
#endif
static struct st7701s_reg st7701s_organize[] = {
{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x10}
},{
.comm = 0xC0,
.val = {0x63,0x00}
},{
.comm = 0xC1,
.val = {0x0A,0x02}
},{
.comm = 0xC2,
.val = {0x31,0x08}
},/*{
.comm = 0xC3,
.val = {0x0C}
},*/{
.comm = 0xCC,
.val = {0x10}
},{
.comm = 0xB0,
.val = {0x00,0x11,0x19,0x0C,0x10,0x06,0x07,0x0A,0x09,0x22,0x04,0x10,0x0E,0x28,0x30,0x1C}
},{
.comm = 0xB1,
.val = {0x00,0x12,0x19,0x0D,0x10,0x04,0x06,0x07,0x08,0x23,0x04,0x12,0x11,0x28,0x30,0x1C}
},{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x11}
},{
.comm = 0xB0,
.val = {0x4D}
},{
.comm = 0xB1,
.val = {0x3E}
},{
.comm = 0xB2,
.val = {0x07}
},{
.comm = 0xB3,
.val = {0x80}
},{
.comm = 0xB5,
.val = {0x47}
},{
.comm = 0xB7,
.val = {0x85}
},{
.comm = 0xB8,
.val = {0x21}
},{
.comm = 0xB9,
.val = {0x10}
},{
.comm = 0xC1,
.val = {0x78}
},{
.comm = 0xC2,
.val = {0x78}
},{
.comm = 0xD0,
.val = {0x88}
},{
.comm = 0xE0,
.val = {0x00,0x00,0x02}
},{
.comm = 0xE1,
.val = {0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x20,0x20}
},{
.comm = 0xE2,
.val = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
},{
.comm = 0xE3,
.val = {0x00,0x00,0x33,0x00}
},{
.comm = 0xE4,
.val = {0x22,0x00}
},{
.comm = 0xE5,
.val = {0x04,0x34,0xAA,0xAA,0x06,0x34,0xAA,0xAA,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
},{
.comm = 0xE6,
.val = {0x00,0x00,0x33,0x00}
},{
.comm = 0xE7,
.val = {0x22,0x00}
},{
.comm = 0xE8,
.val = {0x05,0x34,0xAA,0xAA,0x07,0x34,0xAA,0xAA,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
},{
.comm = 0xEB,
.val = {0x02,0x00,0x40,0x40,0x00,0x00,0x00}
},{
.comm = 0xEC,
.val = {0x00,0x00}
},{
.comm = 0xED,
.val = {0xFA,0x45,0x0B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0,0x54,0xAF}
},{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x00}
},{
.comm = 0x3A,
.val = {0x77}
},{
.comm = 0x36,
.val = {0x08}
}/*,{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x12}
},{
.comm = 0xD1,
.val = {0x81,0x08,0x03,0x20,0x08,0x01,0xA0,0x01,0xE0,0xA0,0x01,0xE0,0x03,0x20}
},{
.comm = 0xD2,
.val = {0x08}
}*/
};
#define PERIEY 1
#define DELAY udelay
static void spi_st7701s_SendData(struct simulation_spi *spi, unsigned char i)
{
unsigned char n;
for(n = 0; n < 8; n++) {
if(i & 0x80) {
SET_HIGH(&spi->data_gpio);
} else {
SET_LOW(&spi->data_gpio);
}
i<<= 1;
SET_LOW(&spi->clk_gpio);
DELAY(PERIEY);
SET_HIGH(&spi->clk_gpio);
DELAY(PERIEY);
}
}
static void spi_st7701s_WriteCommand(struct spi_data *dev, unsigned char i)
{
struct simulation_spi *spi = &dev->spi_di;
SET_LOW(&spi->cs_gpio);
SET_LOW(&spi->data_gpio);
SET_LOW(&spi->clk_gpio);
DELAY(PERIEY);
SET_HIGH(&spi->clk_gpio);
DELAY(PERIEY);
spi_st7701s_SendData(spi, i);
SET_HIGH(&spi->cs_gpio);
}
static void spi_st7701s_WriteData(struct spi_data *dev, unsigned char i)
{
struct simulation_spi *spi = &dev->spi_di;
SET_LOW(&spi->cs_gpio);
SET_HIGH(&spi->data_gpio);
SET_LOW(&spi->clk_gpio);
DELAY(PERIEY);
SET_HIGH(&spi->clk_gpio);
DELAY(PERIEY);
spi_st7701s_SendData(spi ,i);
SET_HIGH(&spi->cs_gpio);
}
#define WRITE_ARRY st7701s_organize
#define LEN_ARRAY(x, y) sizeof(x) / sizeof(y)
void st7701s_driver_open(void)
{
int i, j;
struct spi_data *dev = spi_st7701s_data;
SET_LOW(&dev->spi_di.reset_gpio);
mdelay(10);
SET_HIGH(&dev->spi_di.reset_gpio);
mdelay(120);
spi_st7701s_WriteCommand(dev, 0x11);
udelay(120);
//spi_st7701s_WriteCommand(dev, 0xff);
//spi_st7701s_WriteData(dev, 0xff);
//spi_st7701s_WriteData(dev, 0x98);
//spi_st7701s_WriteData(dev, 0x06);
for (i = 0; i < LEN_ARRAY(WRITE_ARRY, struct st7701s_reg); ++i) {
//LOG("INFO: comm[%d] is = 0x%x \n", i, WRITE_ARRY[i].comm);
spi_st7701s_WriteCommand(dev, WRITE_ARRY[i].comm);
for (j = 0; j < LEN_ARRAY(WRITE_ARRY[i].val, __u8); ++j) {
if (WRITE_ARRY[i].comm == WRITE_ARRY[i].val[j]) {
if (WRITE_ARRY[i].val[j] == 0xB9) {
//LOG("Now Delay 10 ms!\n");
mdelay(10);
}
//LOG("INFO: comm[%d] over! \n", i);
break;
}
//LOG("\t comm[%d], val[%d] is = 0x%x \n", i, j, WRITE_ARRY[i].val[j]);
spi_st7701s_WriteData(dev, WRITE_ARRY[i].val[j]);
}
//LOG("\n");
}
//spi_st7701s_WriteCommand(dev, 0x11);
//mdelay(120);
spi_st7701s_WriteCommand(dev, 0x29);
mdelay(10);
//udelay(10);
//spi_st7701s_WriteCommand(dev, 0x2c);
}
void spi_st7701s_reset(struct spi_data *data)
{
__set_st7701s_gpio(&data->spi_di.reset_gpio, 1);
mdelay(10);
__set_st7701s_gpio(&data->spi_di.reset_gpio, 0);
mdelay(300);
__set_st7701s_gpio(&data->spi_di.reset_gpio, 1);
mdelay(120);
}
static int spi_parse_dt(struct device *dev, struct spi_data *data)
{
struct device_node *np = dev->of_node;
if (!np) {
return -ENODEV;
}
__of_get_named_gpio_flags(np , &(data->spi_di.cs_gpio), "cs-gpio");
__of_get_named_gpio_flags(np , &(data->spi_di.clk_gpio), "clk-gpio");
__of_get_named_gpio_flags(np , &(data->spi_di.data_gpio), "data-gpio");
__of_get_named_gpio_flags(np , &(data->spi_di.reset_gpio), "reset-gpio");
LOG("%s: cs = %d, clk = %d, data = %d, reset = %d\n",
__FUNCTION__,
data->spi_di.cs_gpio.io,
data->spi_di.clk_gpio.io,
data->spi_di.data_gpio.io,
data->spi_di.reset_gpio.io);
return 0;
}
static int st7701s_initialize(struct spi_data *data)
{
if (__rk_setup_gpio(&(data->spi_di.cs_gpio) , "cs-gpio", data->spi_di.cs_gpio.enable) ||
__rk_setup_gpio(&(data->spi_di.clk_gpio) , "clk-gpio", data->spi_di.clk_gpio.enable) ||
__rk_setup_gpio(&(data->spi_di.data_gpio), "data-gpio" , data->spi_di.data_gpio.enable) ||
__rk_setup_gpio(&(data->spi_di.reset_gpio), "reset-gpio" , data->spi_di.reset_gpio.enable)) {
LOG("Failed __rk_setup_gpio. \n");
goto faild_setup_gpio;
}
return 0;
faild_setup_gpio:
return -EIO;
}
static int spi_st7701s_suspend(struct platform_device *spi, pm_message_t mesg)
{
return 0;
}
static int spi_st7701s_resume(struct platform_device *spi)
{
return 0;
}
static int spi_st7701s_probe(struct platform_device *spi)
{
int ret;
struct device *dev = &spi->dev;
struct spi_data *st7701s_data = NULL;
LOG("======Enter %s======\n", __func__);
if (!spi) {
LOG("<---%s---> spi is null!\n", __func__);
return -ENOMEM;
}
st7701s_data = devm_kzalloc(dev, sizeof(struct spi_data), GFP_KERNEL);
if (NULL == st7701s_data) {
LOG("ERR: no memory for st7701s_data!\n");
return -ENOMEM;
}
spi_st7701s_data = st7701s_data;
ret = spi_parse_dt(&spi->dev, st7701s_data);
if (ret < 0) {
LOG("ERR: spi_parse_dt failed!\n");
goto FALLD_PARSE_DTS;
}
if (st7701s_initialize(st7701s_data))
goto FAILD_INITIALIZE;
//spi_st7701s_reset(st7701s_data);
spi_st7701s_data->dev = dev;
st7701s_data->reg = &st7701s_organize[0];
st7701s_driver_open();
return 0;
FAILD_INITIALIZE:
FALLD_PARSE_DTS:
kfree(st7701s_data);
st7701s_data = NULL;
return -EINVAL;
}
static int spi_st7701s_remove(struct platform_device *spi)
{
struct device *dev = &spi->dev;
struct spi_data *st7701s_data = dev_get_drvdata(dev);
LOG("========Enter %s========\n", __func__);
if (NULL == st7701s_data) {
return -ENOMEM;
}
__rk_free_gpio(&(st7701s_data->spi_di.cs_gpio));
__rk_free_gpio(&(st7701s_data->spi_di.clk_gpio));
__rk_free_gpio(&(st7701s_data->spi_di.data_gpio));
__rk_free_gpio(&(st7701s_data->spi_di.reset_gpio));
kfree(st7701s_data);
st7701s_data = NULL;
return 0;
}
#define MODULE_NAME "spi_st7701s"
static const struct of_device_id spi_st7701s_dt_match[] = {
{ .compatible = MODULE_NAME },
{},
};
MODULE_DEVICE_TABLE(of, spi_st7701s_dt_match);
//static const struct spi_device_id spi_st7701s_id[] = {
// {"spi_st7701s", 0},
// {},
//};
static struct platform_driver spi_st7701s_driver = {
.driver = {
.name = MODULE_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(spi_st7701s_dt_match),
},
//.id_table = spi_st7701s_id,
.probe = spi_st7701s_probe,
.remove = spi_st7701s_remove,
.suspend = spi_st7701s_suspend,
.resume = spi_st7701s_resume,
};
static int __init spi_st7701s_init(void)
{
LOG("=======Enter %s=======\n", __func__);
return platform_driver_register(&spi_st7701s_driver);
}
static void __exit spi_st7701s_exit(void)
{
LOG("========Enter %s========\n", __func__);
return platform_driver_unregister(&spi_st7701s_driver);
}
module_init(spi_st7701s_init);
module_exit(spi_st7701s_exit);
MODULE_AUTHOR("arunboy");
MODULE_LICENSE("GPL");
头文件
#ifndef __SPI_ST7701S_H__
#define __SPI_ST7701S_H__
#include <linux/platform_device.h>
#include <linux/platform_data/spi-rockchip.h>
#include <asm/uaccess.h>
#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_fdt.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/dma-mapping.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/miscdevice.h>
#include <asm/dma.h>
#include <linux/preempt.h>
#include <linux/spi/spi.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/pm_runtime.h>
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/vmalloc.h>
#include <linux/kthread.h>
#include <linux/gpio/gpio-rk312x.h>
#define SET_LOW(x) __rk_gpio_set_value(x, STATUS_OFF)
#define SET_HIGH(x) __rk_gpio_set_value(x, STATUS_ON)
#define LOG_TAG "[spi-st7701s]: "
#define LOG(x...) printk(LOG_TAG x)
struct st7701s_reg {
__u8 comm;
__u8 val[150];
};
struct simulation_spi {
struct rk312x_gpio cs_gpio;
struct rk312x_gpio clk_gpio;
struct rk312x_gpio data_gpio;
struct rk312x_gpio reset_gpio;
__u8 (*rw)(struct simulation_spi *spi, unsigned int data, unsigned int len);
};
struct spi_data {
struct device *dev;
//struct spi_device *spi;
struct st7701s_reg *reg;
struct simulation_spi spi_di;
};
void st7701s_driver_open(void);
void st7701s_driver_close(void);
void st7701s_driver_exit(void);
int st7701s_driver_init(void);
void st7701s_set_backlight(int duty);
#define spi_driver_open() st7701s_driver_open()
#define spi_driver_close() st7701s_driver_close()
#define spi_driver_exit() st7701s_driver_exit()
#define spi_driver_init() st7701s_driver_init()
#define spi_driver_backlight(duty) st7701s_set_backlight(duty)
#endif
uboot驱动
#include <errno.h>
#include <common.h>
#include <malloc.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <asm/arch/rkplat.h>
#include <stdlib.h>
#include <power/battery.h>
DECLARE_GLOBAL_DATA_PTR;
#define COMPAT_LCD_ili9806 "spi_ili9806"
#define STATUS_ON 1
#define STATUS_OFF 0
#define set_spi_ili9806_high(x) gpio_direction_output(x, STATUS_ON)
#define set_spi_ili9806_low(x) gpio_direction_output(x, STATUS_OFF)
struct ili9806_reg {
u8 comm;
u8 val[150];
};
struct ili9806_info {
int node;
struct fdt_gpio_state dts_cs;
struct fdt_gpio_state dts_clk;
struct fdt_gpio_state dts_data;
struct ili9806_reg *reg;
};
static struct ili9806_info hi;
extern int __fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
struct fdt_gpio_state *child, int mode);
static struct ili9806_reg ili9806_data[] = {
{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x10}
},{
.comm = 0xC0,
.val = {0x63,0x00}
},{
.comm = 0xC1,
.val = {0x0A,0x02}
},{
.comm = 0xC2,
.val = {0x31,0x08}
},/*{
.comm = 0xC3,
.val = {0x0C}
},*/{
.comm = 0xCC,
.val = {0x10}
},{
.comm = 0xB0,
.val = {0x00,0x11,0x19,0x0C,0x10,0x06,0x07,0x0A,0x09,0x22,0x04,0x10,0x0E,0x28,0x30,0x1C}
},{
.comm = 0xB1,
.val = {0x00,0x12,0x19,0x0D,0x10,0x04,0x06,0x07,0x08,0x23,0x04,0x12,0x11,0x28,0x30,0x1C}
},{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x11}
},{
.comm = 0xB0,
.val = {0x4D}
},{
.comm = 0xB1,
.val = {0x3E}
},{
.comm = 0xB2,
.val = {0x07}
},{
.comm = 0xB3,
.val = {0x80}
},{
.comm = 0xB5,
.val = {0x47}
},{
.comm = 0xB7,
.val = {0x85}
},{
.comm = 0xB8,
.val = {0x21}
},{
.comm = 0xB9,
.val = {0x10}
},{
.comm = 0xC1,
.val = {0x78}
},{
.comm = 0xC2,
.val = {0x78}
},{
.comm = 0xD0,
.val = {0x88}
},{
.comm = 0xE0,
.val = {0x00,0x00,0x02}
},{
.comm = 0xE1,
.val = {0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x20,0x20}
},{
.comm = 0xE2,
.val = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
},{
.comm = 0xE3,
.val = {0x00,0x00,0x33,0x00}
},{
.comm = 0xE4,
.val = {0x22,0x00}
},{
.comm = 0xE5,
.val = {0x04,0x34,0xAA,0xAA,0x06,0x34,0xAA,0xAA,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
},{
.comm = 0xE6,
.val = {0x00,0x00,0x33,0x00}
},{
.comm = 0xE7,
.val = {0x22,0x00}
},{
.comm = 0xE8,
.val = {0x05,0x34,0xAA,0xAA,0x07,0x34,0xAA,0xAA,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
},{
.comm = 0xEB,
.val = {0x02,0x00,0x40,0x40,0x00,0x00,0x00}
},{
.comm = 0xEC,
.val = {0x00,0x00}
},{
.comm = 0xED,
.val = {0xFA,0x45,0x0B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0,0x54,0xAF}
},{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x00}
},{
.comm = 0x3A,
.val = {0x77}
},{
.comm = 0x36,
.val = {0x08}
}/*,{
.comm = 0xFF,
.val = {0x77,0x01,0x00,0x00,0x12}
},{
.comm = 0xD1,
.val = {0x81,0x08,0x03,0x20,0x08,0x01,0xA0,0x01,0xE0,0xA0,0x01,0xE0,0x03,0x20}
},{
.comm = 0xD2,
.val = {0x08}
}*/
};
static void ili9806_SendData(unsigned char i)
{
unsigned char n;
for(n = 0; n < 8; n++) {
if(i & 0x80) {
set_spi_ili9806_high(hi.dts_data.gpio);
} else {
set_spi_ili9806_low(hi.dts_data.gpio);
}
i <<= 1;
set_spi_ili9806_low(hi.dts_clk.gpio);
udelay(1);
set_spi_ili9806_high(hi.dts_clk.gpio);
udelay(1);
}
}
static void ili9806_WriteCommand(unsigned char i)
{
set_spi_ili9806_low(hi.dts_cs.gpio);
set_spi_ili9806_low(hi.dts_data.gpio);
set_spi_ili9806_low(hi.dts_clk.gpio);
udelay(1);
set_spi_ili9806_high(hi.dts_clk.gpio);
udelay(1);
ili9806_SendData(i);
set_spi_ili9806_high(hi.dts_cs.gpio);
}
static void ili9806_WriteData(unsigned char i)
{
set_spi_ili9806_low(hi.dts_cs.gpio);
set_spi_ili9806_high(hi.dts_data.gpio);
set_spi_ili9806_low(hi.dts_clk.gpio);
udelay(1);
set_spi_ili9806_high(hi.dts_clk.gpio);
udelay(1);
ili9806_SendData(i);
set_spi_ili9806_high(hi.dts_cs.gpio);
}
#define WRITE_ARRY ili9806_data
#define LEN_ARRAY(x, y) sizeof(x) / sizeof(y)
void spi_lcd_ili9806_config(void)
{
int row;
int column;
ili9806_WriteCommand(0x11);
udelay(50);
for (row = 0; row < LEN_ARRAY(WRITE_ARRY, struct ili9806_reg); ++row) {
//printf("INFO: comm[%d] is = 0x%x \n", row, WRITE_ARRY[row].comm);
ili9806_WriteCommand(WRITE_ARRY[row].comm);
for (column = 0; column < LEN_ARRAY(WRITE_ARRY[row].val, __u8); ++column) {
if (WRITE_ARRY[row].comm == WRITE_ARRY[row].val[column]) {
//if (WRITE_ARRY[row].val[column] == 0xB9) {
//printf("Now Delay 10 ms!\n");
//mdelay(10);
//}
//printf("INFO: comm[%d] over! \n", row);
break;
}
//printf("\t comm[%d], val[%d] is = 0x%x \n", row, column, WRITE_ARRY[row].val[column]);
ili9806_WriteData(WRITE_ARRY[row].val[column]);
}
//printf("\n");
}
ili9806_WriteCommand(0x29);
udelay(50);
//ili9806_WriteCommand(0x2c);
}
static int spi_lcd_ili9806_parse_dt(const void *blob)
{
hi.node = fdt_node_offset_by_compatible(blob, 0, COMPAT_LCD_ili9806);
if (hi.node < 0) {
printf("can't find dts node for ili9806\n");
return -ENODEV;
}
if (!fdt_device_is_available(blob, hi.node)) {
printf("ili9806 is disabled!\n");
return -EPERM;
}
fdtdec_decode_gpio(blob, hi.node, "cs-gpio", &hi.dts_cs);
hi.dts_cs.flags = !(hi.dts_cs.flags & OF_GPIO_ACTIVE_LOW);
fdtdec_decode_gpio(blob, hi.node, "clk-gpio", &hi.dts_clk);
hi.dts_clk.flags = !(hi.dts_clk.flags & OF_GPIO_ACTIVE_LOW);
fdtdec_decode_gpio(blob, hi.node, "data-gpio", &hi.dts_data);
hi.dts_data.flags = !(hi.dts_data.flags & OF_GPIO_ACTIVE_LOW);
/* Initialize spi gpios, cs:high clk:low data:low */
set_spi_ili9806_high(hi.dts_cs.gpio);
set_spi_ili9806_high(hi.dts_clk.gpio);
set_spi_ili9806_high(hi.dts_data.gpio);
return 0;
}
int spi_lcd_ili9806_init(void)
{
int ret;
if (!hi.node)
#ifdef CONFIG_OF_LIBFDT
printf("spi lcd ili9806 parse dt start\n");
if (!gd->fdt_blob)
return -1;
ret = spi_lcd_ili9806_parse_dt(gd->fdt_blob);
if (ret < 0) {
printf("lcd ili9806 parse dt failed!\n");
return ret;
}
#endif
printf("lcd ili9806 parse dt successfully!\n");
hi.reg = &ili9806_data[0];
spi_lcd_ili9806_config();
printf("lcd ili9806 init over!\n");
return 0;
}
调屏相关总结
如果是spi+rgb形式的,主要调试对象是spi的输出是否能够驱动显示屏正常工作,有些ic是有自检功能的,这个需要找ic的fae询问咨询.rgb的数据正常来说基本不会出现什么问题,只要spi是ok的,那么屏上面肯定有会反应.还有一点需要注意的是spi的gpio口有没有别复用,这个用示波器很容易抓出他们的波形.
如果屏幕出现一些条纹状的斑点,可以往供电方向查一下.
基本上这种spi+rgb的屏幕,spi通信OK了,供电也OK了,基本上不会有什么太大的问题.