RK3128_点亮spi+rgb屏

需求:

在新的平台上点亮一款新的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了,基本上不会有什么太大的问题.

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值