全志f1c100s(tina) linux-3.10 支持spi接口屏移植(1)

本文详述了如何在Linux3.10Tina系统中为f1c100s芯片的显示屏添加SPI支持,包括代码下载、内核配置、驱动文件修改、设备树配置以及fbtft框架的调整,以实现兼容并正确显示SPI屏内容。
摘要由CSDN通过智能技术生成

背景

项目需要,f1c100s的接口本身只有rgb接口,考虑到屏的成本,使用的spi接口屏,但是100s的tina系统没有支持spi接口屏的显示

芯片:f1c100s
系统:tina(linux-3.10)

实现

一、代码下载:

		在内核目录 linux-3.10/driver/video/ 获取:
			git clone https://github.com/notro/fbtft

二、修改:

		a.linux-3.10/drivers/video/Kconfig
		
			source "drivers/video/fbtft/Kconfig"
		
		b.f1c100s\tina\lichee\linux-3.10\drivers\video\Makefile
			
			obj-y += fbtft/

三、修改spi屏配置:

		源码路径(目前修改的是下面驱动屏代码):
		f1c100s\tina\lichee\linux-3.10\drivers\video\fbtft\fb_hx8340bn.c
			1.修改分辨率大小:	
				#define WIDTH		240
				#define HEIGHT		320
				
			2.修改初始化代码:
				static int init_display(struct fbtft_par *par)
				{
					fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
					par->fbtftops.reset(par);
					
					write_reg(par,0xfe);
					write_reg(par,0xef);      
					
					write_reg(par,0x36,0x48);
					
					write_reg(par,0x3a,0x05);
					
					write_reg(par,0x86,0x98);
					
					。。。。。
					 write_reg(par,0x89,0x13);
				}

			3.修改对应spi接口屏的配置
				static struct fbtft_display display = {
					.regwidth = 8,							/*spi屏寄存器的位宽*/
					.width = WIDTH,
					.height = HEIGHT,
					.txbuflen = TXBUFLEN,
					.gamma_num = 2,
					.gamma_len = 15,
					.gamma = DEFAULT_GAMMA,
					.fbtftops = {
					.init_display = init_display,
					.set_addr_win = set_addr_win,		/*窗口设置函数,根据接口屏设置,一般不用修改,					当分辨率对,窗口显示不全是可以考虑此处*/
					/*.set_var = set_var,*/		/*涉及到显示旋转,一般可注释掉*/
					.set_gamma = set_gamma,
					},
				};
				FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", &display);  /*himax,hx8340bn   跟设备树对应上 compatible*/
			4.修改窗口设置函数(改屏需要修改)
				void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
				{
					fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
						"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
				
					write_reg(par, 0x2a, (xs>>8), xs, (xe>>8), xe);
					// ipslcd_write_command(spi, 0x2a);    //列地址设置
				    // ipslcd_write_data8(spi, (x1>>8));
				    // ipslcd_write_data8(spi, x1);
				    // ipslcd_write_data8(spi, (x2>>8));
				    // ipslcd_write_data8(spi, x2);
				
				
					write_reg(par, 0x2b, (ys>>8), ys, (ye>>8), ye);
				    // ipslcd_write_command(spi, 0x2b);    //行地址设置
				    // ipslcd_write_data8(spi, (y1>>8));
				    // ipslcd_write_data8(spi, y1);
				    // ipslcd_write_data8(spi, (y2>>8));
				    // ipslcd_write_data8(spi, y2);
				
					write_reg(par, 0x2c);
				    // ipslcd_write_command(spi, 0x2c);    //存储器写
				
					// write_reg(par, FBTFT_CASET, 0x00, xs, 0x00, xe);
					// write_reg(par, FBTFT_RASET, 0x00, ys, 0x00, ye);
					// write_reg(par, FBTFT_RAMWR);
				}

四、添加设备树配置:

				hy28a@0{
					compatible = "himax,hx8340bn";
					reg = <0>;
					status = "okay";
	
					spi-max-frequency = <50000000>;
					spi-cpol;
					spi-cpha;
					rotate = <0>;
					bgr;
					fps = <50>;
					buswidth = <8>;
					reset-gpios = <&pio PE 10 1 1 1 1>;
					dc-gpios = <&pio PE 11 1 1 1 1>;
					bl-gpios = <&pio PE 12 1 1 1 1>;
					debug = <1>;
				};

五、修改fbtft框架代码(针对linux-3.10的修改):

			源码路径:lichee\linux-3.10\drivers\video\fbtft\fbtft-core.c
1.修改设备树获取函数
					static int fbtft_request_gpios_dt(struct fbtft_par *par)
					{
						int i;
						int ret;
					
						if (!par->info->device->of_node)
							return -EINVAL;
					
						// ret = fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset);
						// if (ret)
						// 	return ret;
						// ret = fbtft_request_one_gpio(par, "dc-gpios", 0, &par->gpio.dc);
						// if (ret)
						// 	return ret;
						// ret = fbtft_request_one_gpio(par, "rd-gpios", 0, &par->gpio.rd);
						// if (ret)
						// 	return ret;
						// ret = fbtft_request_one_gpio(par, "wr-gpios", 0, &par->gpio.wr);
						// if (ret)
						// 	return ret;
						// ret = fbtft_request_one_gpio(par, "cs-gpios", 0, &par->gpio.cs);
						// if (ret)
						// 	return ret;
						// ret = fbtft_request_one_gpio(par, "latch-gpios", 0, &par->gpio.latch);
						// if (ret)
						// 	return ret;
						// for (i = 0; i < 16; i++) {
						// 	ret = fbtft_request_one_gpio(par, "db-gpios", i,
						// 					&par->gpio.db[i]);
						// 	if (ret)
						// 		return ret;
						// 	ret = fbtft_request_one_gpio(par, "led-gpios", i,
						// 					&par->gpio.led[i]);
						// 	if (ret)
						// 		return ret;
						// 	ret = fbtft_request_one_gpio(par, "aux-gpios", i,
						// 					&par->gpio.aux[i]);
						// 	if (ret)
						// 		return ret;
						// }
						par->gpio.reset= of_get_named_gpio(par->info->device->of_node, "reset-gpios", 0);
					    if(par->gpio.reset < 0) 
					    {
							printk("can't get res-gpios");
							return -EINVAL;
						}
					
					    par->gpio.dc = of_get_named_gpio(par->info->device->of_node, "dc-gpios", 0);
					    if(par->gpio.dc < 0) 
					    {
							printk("can't get dc-gpios");
							return -EINVAL;
						}
					
						par->gpio.bl = of_get_named_gpio(par->info->device->of_node, "bl-gpios", 0);
						if(par->gpio.bl < 0) 
					    {
							printk("can't get bl-gpios");
							return -EINVAL;
						}
						ret = gpio_request(par->gpio.reset, "spi-lcd-rst-gpio");
					    if (ret < 0) {
					        printk("gpio %d request fail!\n", par->gpio.reset);
					        return -1;
					    }
					    ret = gpio_request(par->gpio.dc, "spi-lcd-dc-gpio");
					    if (ret < 0) {
					        printk("gpio %d request fail!\n", par->gpio.dc);
					        return -1;
					    }
					
						ret = gpio_request(par->gpio.bl, "spi-lcd-bl-gpio");
					    if (ret < 0) {
					        printk("gpio %d request fail!\n", par->gpio.bl);
					        return -1;
					    }
						 /* 3、设置GPIO初始化输出 */
					    ret = gpio_direction_output(par->gpio.reset, 1);
					    if(ret < 0) 
					    {
							printk("can't set res_gpios!\r\n");
						}
					    ret = gpio_direction_output(par->gpio.dc, 1);
					    if(ret < 0) 
					    {
							printk("can't set dc_gpios!\r\n");
						}
					
						ret = gpio_direction_output(par->gpio.bl, 1);
					    if(ret < 0) 
					    {
							printk("can't set dc_gpios!\r\n");
						}
					
						return 0;
					}



2.修改复位函数(根据spi屏的时序来修改)
				void fbtft_reset(struct fbtft_par *par)
				{
					printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
					if (par->gpio.reset == -1)
						return;
					fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
					printk("%s %d %s\n",__FILE__,__LINE__,__FUNCTION__);
					gpio_set_value(par->gpio.reset, 1);
					msleep(50);
					gpio_set_value(par->gpio.reset, 0);
					msleep(50);
					gpio_set_value(par->gpio.reset, 1);
					msleep(120);
				}
3.修改spi结构体成员变量(添加背光控制引脚)
				struct fbtft_par {
					struct spi_device *spi;
					struct platform_device *pdev;
					struct fb_info *info;
					struct fbtft_platform_data *pdata;
					u16 *ssbuf;
					u32 pseudo_palette[16];
					struct {
						void *buf;
						dma_addr_t dma;
						size_t len;
					} txbuf;
					u8 *buf;
					u8 startbyte;
					struct fbtft_ops fbtftops;
					spinlock_t dirty_lock;
					unsigned dirty_lines_start;
					unsigned dirty_lines_end;
					struct {
						int reset;
						int dc;
						int rd;
						int bl;			==》添加背光控制引脚
						int wr;
						int latch;
						int cs;
						int db[16];
						int led[16];
						int aux[16];
					} gpio;
					int *init_sequence;
					struct {
						struct mutex lock;
						unsigned long *curves;
						int num_values;
						int num_curves;
					} gamma;
					unsigned long debug;
					bool first_update_done;
					struct timespec update_time;
					bool bgr;
					void *extra;
				};
		**最后编译不要忘了选上配置哈,大功告成啦!!!**
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值