RK3128_点亮spi+rgb屏

需求:

在新的平台上点亮一款新的RGB屏.写一个通用的spi驱动代码,以后也可以直接使用.
如果使用linux4.4,这可以直接在dts上面配置即可.本文主要记录下spi的通用驱动.

代码 Kernel修改

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了,基本上不会有什么太大的问题.

原文链接:https://blog.csdn.net/arunboy/article/details/103714996

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容