基于MT7688 原厂SDK 使用SPI控制器驱动TFT屏幕ILI9225驱动器(spi接口)

news/2024/11/19 16:42:36/

以下是我的一个利用SPI控制器操作屏的一个操作实例 包含一个bpeer_tft.c 和一个bpeer_tft.h

这是我基于flash驱动剥离出来的spi控制器驱动

好的话,顶起来~~~~~~~~~~~~~~~~~~~

下面是代码:

bpeer_tft.c

1 /*2  * MTD SPI driver for ST M25Pxx flash chips3  *4  * Author: Mike Lavender, mike@steroidmicros.com5  *6  * Copyright (c) 2005, Intec Automation Inc.7  *8  * Some parts are based on lart.c by Abraham Van Der Merwe9  *10  * Cleaned up and generalized based on mtd_dataflash.c11  *12  * This code is free software; you can redistribute it and/or modify13  * it under the terms of the GNU General Public License version 2 as14  * published by the Free Software Foundation.15  *16  */17 18 #include <linux/init.h>19 #include <linux/module.h>20 #include <linux/device.h>21 #include <linux/interrupt.h>22 #include <linux/interrupt.h>23 #include <linux/mtd/mtd.h>24 #include <linux/mtd/map.h>25 #include <linux/mtd/gen_probe.h>26 #include <linux/mtd/partitions.h>27 #include <linux/semaphore.h>28 #include <linux/slab.h>29 #include <linux/delay.h>30 #include <linux/spi/spi.h>31 #include <linux/spi/flash.h>32 #include <linux/version.h>33 #include <linux/time.h>34 #if defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)35 #else36 #include "ralink_spi.h"37 #endif38 #include <linux/fcntl.h> /* O_ACCMODE */39 #include <linux/types.h> /* size_t */40 #include <linux/proc_fs.h>41 42 43 44 45 #include "bpeer_tft.h"46 47 48 49 50 51 52 53 54 
55 56 //#define SPI_DEBUG57 #if !defined (SPI_DEBUG)58 #define ra_inl(addr)  (*(volatile unsigned int *)(addr))59 #define ra_outl(addr, value)  (*(volatile unsigned int *)(addr) = (value))60 #define ra_dbg(args...) do {} while(0)61 /*#define ra_dbg(args...) do { printk(args); } while(0)*/62 63 #else64 #define ra_dbg(args...) do { printk(args); } while(0)65 #define _ra_inl(addr)  (*(volatile unsigned int *)(addr))66 #define _ra_outl(addr, value)  (*(volatile unsigned int *)(addr) = (value))67 68 u32 ra_inl(u32 addr)69 {70         u32 retval = _ra_inl(addr);71         printk("%s(%x) => %x \n", __func__, addr, retval);72 73         return retval;74 }75 76 u32 ra_outl(u32 addr, u32 val)77 {78         _ra_outl(addr, val);79 80         printk("%s(%x, %x) \n", __func__, addr, val);81 82         return val;83 }84 85 #endif // SPI_DEBUG //86 87 #define ra_aor(addr, a_mask, o_value)  ra_outl(addr, (ra_inl(addr) & (a_mask)) | (o_value))88 #define ra_and(addr, a_mask)  ra_aor(addr, a_mask, 0)89 #define ra_or(addr, o_value)  ra_aor(addr, -1, o_value)90 91 92 93 94 95 96 97 98 99 
100 #define SPI_MAX_DEV 2
101 
102 static struct base_spi spi_pre[SPI_MAX_DEV];
103 static struct tft_config_type tft_config[2];
104 
105 
106 
107 
108 static int spidrv_major = 111;
109 int eye_l_minor =  0;
110 int eye_r_minor =  1;
111 
112 
113 
114 static struct tft_reg_info tft_reg_data [] = {
115         /* init tft reg  */
116         { "rest",               0, 0},
117         { "reg",0x10, 0x0000 }, // Set SAP,DSTB,STB
118         { "reg", 0x11, 0x0000 }, // Set APON,PON,AON,VCI1EN,VC
119         { "reg", 0x12, 0x0000 }, // Set BT,DC1,DC2,DC3
120         { "reg", 0x13, 0x0000 }, // Set GVDD
121         { "reg", 0x14, 0x0000 }, // Set VCOMH/VCOML voltage
122         { "msleep",             40, 0},  //mdelay( 40 }, // Delay 20
123 
124                 // Please follow this power on sequence
125         { "reg", 0x11, 0x0018 }, // Set APON,PON,AON,VCI1EN,VC
126         { "reg", 0x12, 0x1121 }, // Set BT,DC1,DC2,DC3
127         { "reg", 0x13, 0x0063 }, // Set GVDD
128         { "reg", 0x14, 0x3961 }, // Set VCOMH/VCOML voltage
129         { "reg", 0x10, 0x0800 }, // Set SAP,DSTB,STB
130         { "msleep",             10, 0},  //mdelay( 10 }, // Delay 10 ms
131         { "reg", 0x11, 0x1038 }, // Set APON,PON,AON,VCI1EN,VC
132         { "msleep",             30, 0}, //mdelay( 30 }, // Delay 30 ms
133         { "reg", 0x02, 0x0100 }, // set 1 line inversion
134 
135         #if USE_HORIZONTAL//
136                 //R01H:SM=0,GS=0,SS=0 (for details,See the datasheet of ILI9225)
137         { "reg", 0x01, 0x001C }, // set the display line number and display direction
138         //R03H:BGR=1,ID0=1,ID1=1,AM=1 (for details,See the datasheet of ILI9225)
139         { "reg", 0x03, 0x1038 }, // set GRAM write direction .
140         #else
141                 //R01H:SM=0,GS=0,SS=1 (for details,See the datasheet of ILI9225)
142         { "reg", 0x01, 0x011C }, // set the display line number and display direction 
143                 //R03H:BGR=1,ID0=1,ID1=1,AM=0 (for details,See the datasheet of ILI9225)
144         { "reg", 0x03, 0x1030 }, // set GRAM write direction.
145 //      { "reg", 0x03, 0x1020 }, // set GRAM write direction.
146         #endif
147         { "reg", 0x07, 0x0000 }, // Display off
148         { "reg", 0x08, 0x0808 },
149         { "reg", 0x0B, 0x1100 },
150         { "reg", 0x0C, 0x0000 },
151         { "reg", 0x0F, 0x0501 }, // Set Osc
152         { "reg", 0x15, 0x0020 }, // Set VCI recycling
153         { "reg", 0x20, 0x0000 }, // RAM Address
154         { "reg", 0x21, 0x0000 }, // RAM Address
155 
156         //------------------------ Set GRAM area --------------------------------//
157         { "reg", 0x30, 0x0000 },
158         { "reg", 0x31, 0x00DB },
159         { "reg", 0x32, 0x0000 },
160         { "reg", 0x33, 0x0000 },
161         { "reg", 0x34, 0x00DB },
162         { "reg", 0x35, 0x0000 },
163         { "reg", 0x36, 0x00AF },
164         { "reg", 0x37, 0x0000 },
165         { "reg", 0x38, 0x00DB },
166         { "reg", 0x39, 0x0000 },
167 
168 
169         // ---------- Adjust the Gamma 2.2 Curve -------------------//
170         { "reg", 0x50, 0x0603},
171         { "reg", 0x51, 0x080D},
172         { "reg", 0x52, 0x0D0C},
173         { "reg", 0x53, 0x0205},
174         { "reg", 0x54, 0x040A},
175         { "reg", 0x55, 0x0703},
176         { "reg", 0x56, 0x0300},
177         { "reg", 0x57, 0x0400},
178         { "reg", 0x58, 0x0B00},
179         { "reg", 0x59, 0x0017},
180 
181         { "reg", 0x0F, 0x0701}, // Vertical RAM Address Position
182         { "reg", 0x07, 0x0012}, // Vertical RAM Address Position
183         { "msleep", 50, 0}, //mdelay( 50 }, // Delay 50 ms
184         { "reg", 0x07, 0x1017}, // Vertical RAM Address Position 
185 
186 };
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 /*-------------------------GPIO base ----------------------------------------------------------------------*/
202 
203 
204 #define GPIO_OUT_H 1
#define GPIO_OUT_L 0
206 
207 static int base_gpio_set(int gpio,int value)
208 {
209         unsigned int tmp;
210         if (gpio <= 31) {
211                 tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODIR));
212                 tmp |= 1 << gpio;
213                 *(volatile u32 *)(RALINK_REG_PIODIR) = tmp;
214 
215                 tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA));
216                 tmp &= ~(1 << gpio);
217                 tmp |= value << gpio;
218                 *(volatile u32 *)(RALINK_REG_PIODATA) = cpu_to_le32(tmp);
219 //              *(volatile u32 *)(RALINK_REG_PIOSET) = cpu_to_le32(tmp);        
220         } else if (gpio <= 63) {
221                 tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODIR + 0x04));
222                 tmp |= 1 << (gpio - 32);
223                 *(volatile u32 *)(RALINK_REG_PIODIR + 0x04) = tmp;
224 
225                 tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA + 0x04));
226                 tmp &= ~(1 << (gpio - 32));
227                 tmp |= value << (gpio - 32);
228                 *(volatile u32 *)(RALINK_REG_PIODATA + 0x04) = tmp;
229         } else {
230                 tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODIR + 0x08));
231                 tmp |= 1 << (gpio - 64);
232                 *(volatile u32 *)(RALINK_REG_PIODIR + 0x08) = tmp;
233 
234                 tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA + 0x08));
235                 tmp &= ~(1 << (gpio - 64));
236                 tmp |= value << (gpio - 64);
237                 *(volatile u32 *)(RALINK_REG_PIODATA + 0x08) = tmp;
238         }
239 
240 //      *(volatile u32 *)(RALINK_REG_PIOSET) = cpu_to_le32(arg);        
241 }
242 
243 
244 
245 static int  base_gpio_init(void)
246 {
247         unsigned int i;
248         u32 gpiomode;
249 
250         //config these pins to gpio mode
251         gpiomode = le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE));
252         gpiomode &= ~(3<<6);//0xc00;  //clear bit[11:10] 00:SD_mode
253         gpiomode |= (1<<6);//0xc00;  //clear bit[11:10] 00:SD_mode
254         gpiomode &= ~(3<<4);
255 
256 //      *(volatile u32 *)(RALINK_REG_AGPIOCFG) = cpu_to_le32(le32_to_cpu(*(volatile u32 *)(RALINK_REG_AGPIOCFG)) | 0x1e0000 );  //set bit[20:17] 1111:Digital_mode
257 //      gpiomode &= ~0xc00;  //clear bit[11:10] 00:SD_mode
258 //      gpiomode &= ~0x03000000;  //clear bit[25:24] 00:UART1_mode
259 //      gpiomode &= ~0x0300;  //clear bit[9:8] 00:UART0_mode
260         *(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(gpiomode);
261         printk("RALINK_REG_GPIOMODE %08x !\n",le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE)));
262 
263         printk("base_gpio_init initialized\n");
264 
265         base_gpio_set(TFT_GPIO_RS,1);
266         base_gpio_set(TFT_GPIO_LED,0);
267         return 0;
268 }
269 
270 
271 
272 
273 
274 /*-------------------------SPI base ----------------------------------------------------------------------*/
275 
276 
277 #if 0
278 void usleep(unsigned int usecs)
279 {
280         unsigned long timeout = usecs_to_jiffies(usecs);
281 
282         while (timeout)
283                 timeout = schedule_timeout_interruptible(timeout);
284 }
285 #endif
286 
287 static int base_spi_busy_wait(void)
288 {
289         int n = 100000;
290         do {
291                 if ((ra_inl(SPI_REG_CTL) & SPI_CTL_BUSY) == 0)
292                         return 0;
293                 udelay(1);
294         } while (--n > 0);
295 
296         printk("%s: fail \n", __func__);
297         return -1;
298 }
299 
300 static inline u32 base_spi_read( u32 reg)
301 {
302         u32 val;
303         val = ra_inl(reg);
304 //      printk("mt7621_spi_read reg %08x val %08x \n",reg,val);
305         return val;
306 }
307 
308 static inline void base_spi_write( u32 reg, u32 val)
309 {
310 //      printk("mt7621_spi_write reg %08x val %08x \n",reg,val);
311         ra_outl(reg,val);
312 }
313 
314 static void base_spi_reset(int duplex) // 0 half duplex ; 1 full duplex
315 {
316         u32 master = base_spi_read(SPI_REG_MASTER);
317 
318         master |= 7 << 29;
319         master |= 1 << 2;
320         if (duplex)
321                 master |= 1 << 10;
322         else
323                 master &= ~(1 << 10);
324         base_spi_write(SPI_REG_MASTER, master);
325 }
326 
327 static void base_spi_set_cs(struct base_spi *spi, int enable)
328 {
329         int cs = spi->chip_select;
330         u32 polar = 0;
331         base_spi_reset(0);
332         if(cs > 1)
333                 base_gpio_set(cs,GPIO_OUT_H);
334         if (enable){
335                 if(cs > 1)
336                         base_gpio_set(cs,GPIO_OUT_L);
337                 else
338                         polar = BIT(cs);
339                 }
340         base_spi_write(SPI_REG_CS_POLAR, polar);
341 }
342 
343 static int base_spi_prepare(struct base_spi* spi)
344 {
345         u32 rate;
346         u32 reg;
347 
348 //      printk("speed:%u\n", spi->speed);
349 
350         rate = DIV_ROUND_UP(spi->sys_freq,spi->speed);
351 //      printk( "rate-1:%u\n", rate);
352 
353         if (rate > 4097)
354                 return -EINVAL;
355 
356         if (rate < 2)
357                 rate = 2;
358 
359         reg = base_spi_read(SPI_REG_MASTER);
360         reg &= ~(0xfff << 16);
361         reg |= (rate - 2) << 16;
362 
363         reg &= ~SPI_REG_LSB_FIRST;
364         if (spi->mode & SPI_LSB_FIRST)
365                 reg |= SPI_REG_LSB_FIRST;
366 
367         reg &= ~(SPI_REG_CPHA | SPI_REG_CPOL);
368         switch(spi->mode & (SPI_CPOL | SPI_CPHA)) {
369                 case SPI_MODE_0:
370                         break;
371                 case SPI_MODE_1:
372                         reg |= SPI_REG_CPHA;
373                         break;
374                 case SPI_MODE_2:
375                         reg |= SPI_REG_CPOL;
376                         break;
377                 case SPI_MODE_3:
378                         reg |= SPI_REG_CPOL | SPI_REG_CPHA;
379                         break;
380         }
381         base_spi_write(SPI_REG_MASTER, reg);
382 
383         return 0;
384 }
385 
386 
387 static int base_spi_transfer_half_duplex(struct base_spi *m)
388 {
389         unsigned long flags;
390         int status = 0;
391         int i, len = 0;
392         int rx_len = 0;
393         u32 data[9] = { 0 };
394         u32 val;
395         spin_lock_irqsave(&m->lock, flags);
396         base_spi_busy_wait();
397 
398         u8 *buf = m->tx_buf;
399         for (i = 0; i < m->tx_len; i++, len++)
400                 data[len / 4] |= buf[i] << (8 * (len & 3));
401         if (WARN_ON(rx_len > 32)) {
402                 status = -EIO;
403                 goto msg_done;
404         }
405 
406         if (base_spi_prepare(m)) {
407                 status = -EIO;
408                 goto msg_done;
409         }
410 
411         data[0] = swab32(data[0]);
412         if (len < 4)
413                 data[0] >>= (4 - len) * 8;
414 
415         for (i = 0; i < len; i += 4)
416                 base_spi_write(SPI_REG_OPCODE + i, data[i / 4]);
417 
418         val = (min_t(int, len, 4) * 8) << 24;
419         if (len > 4)
420                 val |= (len - 4) * 8;
421         val |= (rx_len * 8) << 12;
422         base_spi_write(SPI_REG_MOREBUF, val);
423 
424         base_spi_set_cs(m, 1);
425 
426         val = base_spi_read(SPI_REG_CTL);
427         val |= SPI_CTL_START;
428         base_spi_write(SPI_REG_CTL, val);
429 
430         base_spi_busy_wait();
431 
432         base_spi_set_cs(m, 0);
433 
434         for (i = 0; i < rx_len; i += 4)
435                 data[i / 4] = base_spi_read(SPI_REG_DATA0 + i);
436 
437         len = 0;
438         buf = m->rx_buf;
439         for (i = 0; i < m->rx_len; i++, len++)
440                 buf[i] = data[len / 4] >> (8 * (len & 3));
441 
442 msg_done:
443         spin_unlock_irqrestore(&m->lock, flags);
444 //      m->status = status;
445 //      spi_finalize_current_message(master);
446 
447         return status;
448 }
449 
450 
451 /*-------------------------TFT ----------------------------------------------------------------------*/
452 
453 
454 
455 static int tft_write_index(struct base_spi* spi, char reg)
456 {
457         int retval;
458         base_gpio_set(TFT_GPIO_RS,0);
459         spi->tx_buf[0] = reg;
460         spi->tx_len = 1;
461         retval = base_spi_transfer_half_duplex(spi);
462         if (retval != 0) {
463                 printk("%s: ret: %x\n", __func__, retval);
464         }
465         return retval;
466 }
467 
468 static int tft_write_data(struct base_spi* spi, unsigned char* data,int length)
469 {
470         int retval;
471         int i = 0;
472         int j = 0;
473         int n = 0;
474         base_gpio_set(TFT_GPIO_RS,1);
475         int step = 4;
476         unsigned char* buf;
477 
478         while((length - j) > 0){
479 //              printk("%s: ret: %d  j %d\n", __func__, length,j);
480                 buf =  data + j;
481                 n = length - j;
482                 if(n >= step)
483                         n = step;
484                 for(i = 0; i < n; i++){
485                         spi->tx_buf[i] = buf[n - i -1];
486                 }
487                 spi->tx_len = n;
488 //              printk("data: %02x %02x %02x %02x \n", spi->tx_buf[0],spi->tx_buf[1],spi->tx_buf[2],spi->tx_buf[3]);
489                 retval = base_spi_transfer_half_duplex(spi);
490                 j += n;
491                 }
492 
493         return retval;
494 }
495 static int write_data(struct base_spi* spi, unsigned char* data,int length)
496 {
497         int retval;
498         int i = 0;
499         int j = 0;
500         int n = 0;
501         base_gpio_set(TFT_GPIO_RS,1);
502         int step = 32;
503         unsigned char* buf;
504 
505         while((length - j) > 0){
506 //              printk("%s: ret: %d  j %d\n", __func__, length,j);
507                 buf =  data + j;
508                 n = length - j;
509                 if(n >= step)
510                         n = step;
511                 for(i = 0; i < n; i++){
512                         spi->tx_buf[i] = buf[i];
513                 }
514                 spi->tx_len = n;
515 //              printk("data: %02x %02x %02x %02x \n", spi->tx_buf[0],spi->tx_buf[1],spi->tx_buf[2],spi->tx_buf[3]);
516                 retval = base_spi_transfer_half_duplex(spi);
517                 j += n;
518                 }
519 
520 
521         return retval;
522 
523 }
524 
525 
526 static int tft_write_reg(struct base_spi* spi, char reg, char* data, int length)
527 {
528         int retval;
529         tft_write_index( spi,reg);
530         tft_write_data( spi, data,length);
531 
532         return retval;
533 }
534 
535 
536 
537 
538 
539 static void
540 Lcd_SetRegion( struct base_spi* spi, unsigned char xStar, unsigned char yStar, unsigned char xEnd, unsigned char yEnd )
541 {
542         char buf = 0;
543         int err;
544         #if   USE_HORIZONTAL
545                 tft_write_reg( spi, 0x38, &xEnd  ,2);
546                 tft_write_reg( spi, 0x39, &xStar ,2);
547                 tft_write_reg( spi, 0x36, &yEnd  ,2);
548                 tft_write_reg( spi, 0x37, &yStar ,2);
549                 tft_write_reg( spi, 0x21, &xStar ,2);
550                 tft_write_reg( spi, 0x20, &yStar ,2);
551         #else
552 //              tft_write_reg( spi, 0x36, &xEnd, 2);
553 //              tft_write_reg( spi, 0x37, &xStar, 2);
554 //              tft_write_reg( spi, 0x38, &yEnd,  2);
555 //              tft_write_reg( spi, 0x39, &yStar, 2);
556 ///             tft_write_reg( spi, 0x20, &xStar, 2);
557 //              tft_write_reg( spi, 0x21, &yStar, 2);
558 
559                 tft_write_reg( spi, 0x36, &yEnd, 2);
560                 tft_write_reg( spi, 0x37, &yStar, 2);
561                 tft_write_reg( spi, 0x38, &xEnd,  2);
562                 tft_write_reg( spi, 0x39, &xStar, 2);
563                 tft_write_reg( spi, 0x20, &xStar, 2);
564                 tft_write_reg( spi, 0x21, &yStar, 2);
565 
566 
567         #endif
568         tft_write_index( spi, 0x22);
569 
570 }
571 
572 
573 static void Lcd_Clear( struct base_spi* spi, unsigned short Color)
574 {
575         unsigned int i,m;
576         Lcd_SetRegion( spi, 0, 0, X_MAX_PIXEL-1, Y_MAX_PIXEL-1 );
577         for( i =0; i < X_MAX_PIXEL; i++ )
578                 for( m = 0; m < Y_MAX_PIXEL ; m++ ){
579                         tft_write_data( spi, &Color,2);
580                 }
581 }
582 static void Lcd_Clear1( struct base_spi* spi, unsigned short Color)
583 {
584         unsigned int i,m;
585 //      Lcd_SetRegion( spi, 0, 0, X_MAX_PIXEL-1, Y_MAX_PIXEL-1 );
586         Lcd_SetRegion( spi, 0, 0, X_MAX_PIXEL-1, Y_MAX_PIXEL-1 );
587 //      for( i =0; i < X_MAX_PIXEL; i++ )
588         for( i =0; i < 1; i++ )
589                 for( m = 0; m < 10 ; m++ ){
590                         tft_write_data( spi, &Color,2);
591                 }
592 }
593 
594 
595 
596 
597 
598 
599 static ssize_t tft_write(struct file *file, const char __user *buf,
600                                                 size_t count, loff_t *ppos)
601 {
602         struct timeval  tval1, tval2, tval3, tval4, tval5, tval6, tval7;
603 //      do_gettimeofday( &tval1 );
604         struct tft_config_type* ptrtft_config;
605         unsigned long flags;
606         unsigned char* data;//[200*250*2];      
607         int minor ; // = iminor(inode);
608 //      Lcd_SetRegion( spi, X_MAX_PIXEL-1, Y_MAX_PIXEL-1, 0, 0 );
609         data = kzalloc(200*250*2, GFP_KERNEL);
610 //      printk("tft_write: %d %x\n",data,data);
611 //      do_gettimeofday( &tval2 );
612 
613 
614         ptrtft_config = file->private_data;
615 //      spin_lock_irq( &ptrtft_config->spi->lock );
616         Lcd_SetRegion( ptrtft_config->spi, 0, 0, X_MAX_PIXEL-1, Y_MAX_PIXEL-1 );
617 //      Lcd_SetRegion( ptrtft_config->spi, Y_MAX_PIXEL-1, X_MAX_PIXEL, 0, 0 );
618 //      do_gettimeofday( &tval3 );
619 
620 //      Lcd_SetRegion( ptrtft_config->spi, X_MAX_PIXEL-1, Y_MAX_PIXEL-1, 0, 0 );
621         copy_from_user( data, buf, count );
622 //      do_gettimeofday( &tval4 );
623 
624         count = write_data(ptrtft_config->spi, data, count);
625 //      do_gettimeofday( &tval5 );
626         kfree(data);
627 //      do_gettimeofday( &tval6 );
628         data = NULL;
629 //      spin_unlock_irq( &ptrtft_config->spi->lock );
630         base_gpio_set(TFT_GPIO_LED,1);
631 //      do_gettimeofday( &tval7 );
632 //      do_gettimeofday( &tval2 );
633 //      printk("---------syscall_write_time= time2 - time1----------\n");
634 //      printk("timeval2->tv_sec - timeval1->tv_sec=%ld\n",tval2.tv_sec - tval1.tv_sec);
635 //      printk("timeval2->tv_usec - timeval2->tv_usec=%ld\n",tval2.tv_usec - tval1.tv_usec);
636 /*
637         printk("\n");
638         printk("-------kzalloc_time = time2 - time1-----------------\n");
639         printk("timeval2->tv_sec - timeval1->tv_sec=%ld\n",tval2.tv_sec - tval1.tv_sec);
640         printk("timeval2->tv_usec - timeval2->tv_usec=%ld\n",tval2.tv_usec - tval1.tv_usec);
641         printk("---------Lcd_SetRgion_time = time3 - time2------------\n");
642         printk("timeval3->tv_sec - timeval2->tv_sec=%ld\n",tval3.tv_sec - tval2.tv_sec);
643         printk("timeval3->tv_usec - timeval2->tv_usec=%ld\n",tval3.tv_usec - tval2.tv_usec);
644         printk("--------------copy_from_user_time = time4 -time3-----------\n");
645         printk("timeval4->tv_sec - timeval3->tv_sec=%ld\n",tval4.tv_sec - tval3.tv_sec);
646         printk("timeval4->tv_usec - timeval3->tv_usec=%ld\n",tval4.tv_usec - tval3.tv_usec);
647         printk("--------------write_data_time = time5 - time4--------------\n");
648         printk("timeval5->tv_sec - timeval4->tv_sec=%ld\n",tval5.tv_sec - tval4.tv_sec);
649         printk("timeval5->tv_usec - timeval4->tv_usec=%ld\n",tval5.tv_usec - tval4.tv_usec);
650         printk("--------------kfree()_time = time6 - time5------------------\n");
651         printk("timeval6->tv_sec - timeval5->tv_sec=%ld\n",tval6.tv_sec - tval5.tv_sec);
652         printk("timeval6->tv_usec - timeval5->tv_usec=%ld\n",tval6.tv_usec - tval5.tv_usec);
653         printk("--------------gpio_set_time = time7 - time6------------------\n");
654         printk("timeval7->tv_sec - timeval6->tv_sec=%ld\n",tval7.tv_sec - tval6.tv_sec);
655         printk("timeval7->tv_usec - timeval6->tv_usec=%ld\n",tval7.tv_usec - tval6.tv_usec);
656         printk("---------------All End---------------------\n");
657         printk("\n");
658 */
659         return count;
660 }
661 
662 
663 long tft_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
664 {
665         int i ;
666         char* data;
667         void __user *argp = (void __user *)arg;
668         int __user *p = argp;
669         struct tft_config_type* ptrtft_config;
670         unsigned long flags;
671         struct base_spi* spi;
672         ptrtft_config = filp->private_data;
673         spi = ptrtft_config->spi;
674         switch (cmd) {
675         case TFT_RESET:
676 
677                 break;
678         case TFT_SET_REG:
679 
680                 break;
681         case TFT_GET_REG:
682                 copy_to_user(argp, data, sizeof(data)) ? -EFAULT : 0;
683 
684 
685                 break;
686         case TFT_DEBUG:
687                 break;
688         default :
689                 printk("TFT_ioctl: command format error\n");
690         }
691 
692         return 0;
693 }
694 
695 
696 
697 int reset = 0;
698 static int tft_param_init(struct tft_config_type* ptrtft_config)
699 {
700         struct tft_reg_info *info;
701         int i = 0;
702         int err;
703         u16 buff = 0x4255;
704 
705 
706 //      tft_write_reg( ptrtft_config->spi, 0x38, &buff  ,2);
707 
708 #if 1
709         for (i = 0; i < ARRAY_SIZE(tft_reg_data); i++) {
710                 info = &tft_reg_data[i];
711 //              printk("tft_param_init tft_reg_data %d %s %x %x\n",i, info->name,info->reg,info->val);
712                 if(strcmp(info->name,"reg")==0) {
713                         err = tft_write_reg(ptrtft_config->spi,info->reg,&info->val,2);
714                         if(err < 0){
715                                 printk("init tft Successful!\n");
716                                 return err;
717                                 }
718                         }
719                 if(strcmp(info->name,"msleep")==0) {
720                         mdelay(info->reg);
721                         }
722                 if(strcmp(info->name,"rest")==0) {
723                         if(reset == 0){
724                                 base_gpio_set(TFT_GPIO_RESET,0);
725                                 mdelay(100);
726                                 base_gpio_set(TFT_GPIO_RESET,1);
727                                 mdelay(50);
728                                 reset = 1;
729                                 }
730                         }
731                 }
732 #endif
733         printk("init tft Successful!\n");
734         return 0;
735 }
736 
737 
738 
739 
740 
741 
742 
743 int tft_open(struct inode *inode, struct file *filp)
744 {
745         struct base_spi* spi_init;
746         int chip_select = 0;
747         int minor = iminor(inode);
748         if(minor == eye_l_minor){
749                 chip_select = TFT_EYEL_CS;
750                 printk("tft_open eye lift  minor %d !\n", minor);
751                 }
752         if(minor == eye_r_minor){
753                 chip_select = TFT_EYER_CS;
754                 printk("tft_open eye right   minor %d ! \n", minor);
755                 }
756 
757         if ((minor != eye_l_minor)&&(minor != eye_r_minor)){
758                 printk("minor is error minor %d ! \n", minor);
759                 return -ENODEV;
760                 }
761         printk("%s was called\n",__func__);
762 
763         tft_config[minor].spi = &spi_pre[minor];
764         spi_init = tft_config[minor].spi;
765 //      spi_init->start = kmalloc(200*250*2, GFP_KERNEL);
766 //      if( !spi_init->start)
767 //      {
768 //              printk(" kmalloc is failed was open()");
769 //              return -ENOMEM;
770 //      }
771 
772         spi_init->chip_select = chip_select;
773         spi_init->mode = SPI_MODE_3;
774         spi_init->speed = 50000000;
775         spi_init->sys_freq = 575000000;
776         spin_lock_init(&spi_init->lock);
777         tft_param_init(&tft_config[minor]);
778 
779         filp->private_data = &tft_config[minor];
780         printk("%s was End\n",__func__);
781 
782         base_gpio_set(TFT_GPIO_LED,1);
783 //      mdelay(3000);
784 
785 //      Lcd_Clear(spi_init, 0x001f);
786 //      mdelay(3000);
787 //      Lcd_Clear(spi_init, 0x07e0);
788 //      mdelay(3000);
789 //      Lcd_Clear(spi_init, 0xf800);
790         Lcd_Clear(spi_init, 0x0);
791 //      Lcd_Clear1(spi_init, 0xf800);
792 //      base_gpio_set(TFT_GPIO_LED,1);
793 //      try_module_get(THIS_MODULE);
794 //      if (filp->f_flags & O_NONBLOCK) {
795 //              printk("filep->f_flags O_NONBLOCK set\n");
796 //              return -EAGAIN;
797 //      }
798         return 0;
799 }
800 
801 
802 static int tft_release(struct inode *inode, struct file *filp)
803 {
804         /************Liuchen modfiy here***************/
805         struct tft_config_type* tmp = filp->private_data;
806         spin_lock_irq( &tmp->spi->lock );
807         kfree( tmp->spi->start);
808         spin_unlock_irq( &tmp->spi->lock );
809         /*************END******************************/
810         printk("tft_release 1  !\n");
811 
812         filp->private_data=NULL;
813 
814         return 0;
815 }
816 
817 
818 static const struct file_operations tft_fops = {
819         .owner          = THIS_MODULE,
820         .open           = tft_open,
821         .write          = tft_write,
822         .release        = tft_release,
823         .unlocked_ioctl = tft_ioctl,
824 };
825 
826 
827 
828 struct class *my_class;
829 static int __init tft_init(void)
830 {
831 
832         int result=0, i = 0;
833 /*
834         struct base_spi *dev; 
835         struct tft_config_type *tmp;
836         for( i =0; i < SPI_MAX_DEV; i++) 
837         {
838                 dev = (struct base_spi*)kzalloc(sizeof(*dev), GFP_KERNEL);
839                 if(!dev){
840                         return -ENOMEM;
841                 }
842                 dev->start = kzalloc(200*250*2, GFP_KERNEL);
843                 if( !dev->start ){
844                         return -ENOMEM;
845                 }
846                 
847                 tmp = (struct tft_config_type*)kzalloc(sizeof(*tmp), GFP_KERNEL);
848                 if(!tmp){
849                         return -ENOMEM;
850                 }
851                 spi_pre[i] = dev;
852                 tft_config[i] = spi_pre[i];             
853         }       
854 */
855         result = register_chrdev(spidrv_major, "TFT", &tft_fops);
856         printk("creat %s major %d  %d!\n","TFT",spidrv_major,result);
857         if (result < 0) {
858                 printk(KERN_WARNING "i2s: can't get major %d\n",spidrv_major);
859                 return result;
860         }
861 
862         my_class=class_create(THIS_MODULE, "TFT");
863         if (IS_ERR(my_class))
864                 return -EFAULT;
865         device_create(my_class, NULL, MKDEV(spidrv_major, eye_l_minor), NULL,TFT_LIFT_DEVNAME);
866         device_create(my_class, NULL, MKDEV(spidrv_major, eye_r_minor), NULL,TFT_RIGHT_DEVNAME);
867 
868 
869 
870         if (spidrv_major == 0) {
871                 spidrv_major = result; /* dynamic */
872         }
873         base_gpio_init();
874 
875 
876 
877 #if 0
878         u32 gpiomode;
879         //config these pins to gpio mode
880         gpiomode = le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE));
881         printk("RALINK_REG_GPIOMODE %08x !\n",gpiomode);
882 
883         base_gpio_set(11,1);
884         mdelay(100);
885         base_gpio_set(11,0);
886         mdelay(100);
887         base_gpio_set(11,1);
888         mdelay(100);
889 
890         
891         struct base_spi* spi_init;
892 
893         spi_init = &spi_pre[0];
894         spi_init->chip_select = 1;
895         spi_init->mode = SPI_MODE_3 ;
896         spi_init->speed = 40000000;
897         spi_init->sys_freq = 575000000;
898 
899 
900         spi_init->tx_buf[0] = 0xa5;
901         spi_init->tx_buf[1] = 0x8b;
902         spi_init->tx_len = 2;
903 
904         base_spi_transfer_half_duplex(spi_init);
905 #endif
906         printk("insmod tft driver end !\n");
907 
908         return 0;
909 }
910 /*
911 static void dev_release(void)
912 {
913         int i;
914         for(i = 0; i < 2; i++)
915         {
916                 if(spi_pre[i]){
917                         kfree()
918                 }
919                 
920         }
921 }
922 */
923 static void __exit tft_exit(void)
924 {
925 //              dev_t devno = MKDEV (hello_major, hello_minor);  
926         printk("rmmod tft driver!\n");
927         device_destroy(my_class, MKDEV(spidrv_major, eye_l_minor));                //delete device node under /dev      
928         device_destroy(my_class, MKDEV(spidrv_major, eye_r_minor));                //delete device node under /dev      
929         class_destroy(my_class);                                                           //delete class created by us  
930         unregister_chrdev(spidrv_major, "TFT");
931         printk("rmmod tft driver!\n");
932 }
933 
934 
935 module_init(tft_init);
936 module_exit(tft_exit);

下面是bpeer_tft.h文件1 #ifndef __TFT__
  2 #define __TFT__
  3 #include <asm/mach-ralink/rt_mmap.h>
  4
  5 #define TFT_EYE_VERSION         "1.0"
  6 #define TFT_LIFT_DEVNAME        "eye_L"
  7 #define TFT_RIGHT_DEVNAME       "eye_R"
  8
  9
 10
 11 #define TFT_IOCTL_BASE  'M'
 12
 13 struct tft_reg_info {
 14         char*   name;
 15         u8              reg;
 16         u16             val;
 17 };
 18
 19 #define TFT_RESET               _IOR(TFT_IOCTL_BASE, 0, int)
 20 #define TFT_SET_REG             _IOR(TFT_IOCTL_BASE, 1, struct tft_reg_info)
 21 #define TFT_GET_REG             _IOR(TFT_IOCTL_BASE, 2, struct tft_reg_info)
 22 #define TFT_DEBUG               _IOR(TFT_IOCTL_BASE, 3, int)
 23
 24 #define TFT_GPIO_RESET          3
 25 #define TFT_GPIO_RS             2
 26 #define TFT_GPIO_LED            0
 27 #define TFT_EYER_CS             11
 28 #define TFT_EYEL_CS             1
 29
 30
 31
 32 //define GPIO39         RS      pin
 33 //define GPIO40         REST    pin
 34 //define GPIO41         LED     pin
 35 #define GPIO39          39
 36 #define GPIO40          40
 37 #define GPIO41          41
 38 #define LED_ON          1
 39 #define DEV_NAME                "bptft"
 40 #define BUF_SIZE                80000
 41 #define DEV_NUM                 2
 42 #define SYS_CTRL                0XB0000000
 43 #define GPIOMODE2_BASE          (SYS_CTRL + 0x64)  //configure to gpio mode
 44 #define GPIOMODE2_CTRL_BASE     (SYS_CTRL + 0x604) //configure to output mode
 45 #define GPIOMODE2_DATA_BASE     (SYS_CTRL + 0x624) //configure register up or down
 46
 47 #define LCD_X_SIZE      176
 48 #define LCD_Y_SIZE      220
 49 #define USE_HORIZONTAL  0
 50
 51 #ifdef USE_HORIZONTAL //使用横屏
 52 #define X_MAX_PIXEL     LCD_Y_SIZE
 53 #define Y_MAX_PIXEL     LCD_X_SIZE
 54 #else//使用竖屏

55 #define X_MAX_PIXEL     LCD_X_SIZE
 56 #define Y_MAX_PIXEL     LCD_Y_SIZE
 57 #endif
 58
 59
 60
 61
 62
 63
 64 /*    ------------------------------------spi----------------------------------------------------      */
 65 #define SPI_REG_CTL             (RALINK_SPI_BASE + 0x00)
 66
 67 #define SPI_REG_CTL             (RALINK_SPI_BASE + 0x00)
 68 #define SPI_REG_OPCODE          (RALINK_SPI_BASE + 0x04)
 69 #define SPI_REG_DATA0           (RALINK_SPI_BASE + 0x08)
 70 #define SPI_REG_DATA(x)         (SPI_REG_DATA0 + (x * 4))
 71 #define SPI_REG_MASTER          (RALINK_SPI_BASE + 0x28)
 72 #define SPI_REG_MOREBUF         (RALINK_SPI_BASE + 0x2c)
 73 #define SPI_REG_Q_CTL           (RALINK_SPI_BASE + 0x30)
 74 #define SPI_REG_CS_POLAR        (RALINK_SPI_BASE + 0x38)
 75 #define SPI_REG_SPACE_CR        (RALINK_SPI_BASE + 0x3c)
 76
 77 #define SPI_CTL_START           0x00000100
 78 #define SPI_CTL_BUSY            0x00010000
 79 #define SPI_CTL_TXCNT_MASK      0x0000000f
 80 #define SPI_CTL_RXCNT_MASK      0x000000f0
 81 #define SPI_CTL_TX_RX_CNT_MASK  0x000000ff
 82 #define SPI_CTL_SIZE_MASK       0x00180000
 83 #define SPI_CTL_ADDREXT_MASK    0xff000000
 84
 85 #define SPI_MBCTL_TXCNT_MASK            0x000001ff
 86 #define SPI_MBCTL_RXCNT_MASK            0x001ff000
 87 #define SPI_MBCTL_TX_RX_CNT_MASK        (SPI_MBCTL_TXCNT_MASK | SPI_MBCTL_RXCNT_MASK)
 88 #define SPI_MBCTL_CMD_MASK              0x3f000000
 89
 90 #define SPI_CTL_CLK_SEL_MASK    0x03000000
 91 #define SPI_OPCODE_MASK         0x000000ff
 92
 93 #define SPI_STATUS_WIP          STM_STATUS_WIP
 94
 95 #define SPI_REG_CPHA            BIT(5)
 96 #define SPI_REG_CPOL            BIT(4)
 97 #define SPI_REG_LSB_FIRST       BIT(3)
 98 #define SPI_REG_MODE_BITS       (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH)
 99
100 #define SPI_CPHA                0x01
101 #define SPI_CPOL                0x02
102
103 #define SPI_MODE_0              (0|0)

104 #define SPI_MODE_1              (0|SPI_CPHA)
105 #define SPI_MODE_2              (SPI_CPOL|0)
106 #define SPI_MODE_3              (SPI_CPOL|SPI_CPHA)
107
108 #define SPI_CS_HIGH             0x04
109 #define SPI_LSB_FIRST           0x08
110 #define SPI_3WIRE               0x10
111 #define SPI_LOOP                0x20
112 #define SPI_NO_CS               0x40
113 #define SPI_READY               0x80
114
115
116
117 struct base_spi {
118         struct clk              *clk;
119         spinlock_t              lock;
120         unsigned int    speed;
121         unsigned int    sys_freq;
122         unsigned char           *start;
123         u32                     max_speed_hz;
124         u8                      chip_select;
125         u8                      mode;
126         u8                      tx_buf[36];
127         u8                      tx_len;
128         u8                      rx_buf[36];
129         u8                      rx_len;
130 };
131
132
133
134 struct tft_config_type {
135         struct base_spi* spi;
136
137 };
138
139
140 /* ------------------------------GPIO---------------------------------------------- */
141 #include <asm/rt2880/rt_mmap.h>
142
143 #define RALINK_SYSCTL_ADDR              RALINK_SYSCTL_BASE      // system control
144 #define RALINK_REG_GPIOMODE             (RALINK_SYSCTL_ADDR + 0x60)
145
146 #define RALINK_IRQ_ADDR                 RALINK_INTCL_BASE
147 #define RALINK_PRGIO_ADDR               RALINK_PIO_BASE // Programmable I/O
148
149 #define RALINK_REG_INTENA               (RALINK_IRQ_ADDR   + 0x80)
150 #define RALINK_REG_INTDIS               (RALINK_IRQ_ADDR   + 0x78)
151

152 #define RALINK_REG_PIOINT               (RALINK_PRGIO_ADDR + 0x90)
153 #define RALINK_REG_PIOEDGE              (RALINK_PRGIO_ADDR + 0xA0)
154 #define RALINK_REG_PIORENA              (RALINK_PRGIO_ADDR + 0x50)
155 #define RALINK_REG_PIOFENA              (RALINK_PRGIO_ADDR + 0x60)
156 #define RALINK_REG_PIODATA              (RALINK_PRGIO_ADDR + 0x20)
157 #define RALINK_REG_PIODIR               (RALINK_PRGIO_ADDR + 0x00)
158 #define RALINK_REG_PIOSET               (RALINK_PRGIO_ADDR + 0x30)
159 #define RALINK_REG_PIORESET             (RALINK_PRGIO_ADDR + 0x40)
160
161
162 #endif

如有疑问,请指出,多多交流


http://www.ppmy.cn/news/803678.html

相关文章

基于51单片机MAX6675 MAX1241的热电偶测温电机驱动系统proteus仿真 程序设计

硬件设计 &#xff08;末尾附文件&#xff09; 1&#xff0e;采用AT89C51单片机作为控制器&#xff0c;分别对温度采集、LCD显示。 2&#xff0e;温度测量模块采用K\热电偶与MAX6775相结合可实现冷端温度补偿高分辨率测量 3&#xff0e;显示用液晶显示屏显示实时温度值。 4. …

FS_S5PC100平台上Linux Camera驱动开发详解

转自&#xff1a;http://mobile.riaos.com/?p2005569 说明&#xff1a; 理解摄像头驱动需要四个前提&#xff1a; 1&#xff09;摄像头基本的工作原理和S5PC100集成的Camera控制器的工作原理 2&#xff09;platform_device和platform_driver工作原理 …

vkms驱动移植及测试程序移植(基于imx6ull平台)

移植vkms 到Linux-4.9.88内核(基于100ask_imx6ull_pro开发板) 何小龙老师-Blog主页 何小龙老师的DRM系列专栏文章&#xff0c;非常适合系统入门学习DRM&#xff0c;DRM 系列非常精彩 VKMS简介 VKMS 是 “Virtual Kernel Mode Setting” 的缩写&#xff0c;它于2018年7月5日被…

DM9000C网卡驱动程序编写与测试

一般网卡驱动程序厂商会给我们提供一份模板驱动,我们的工作就是需要根据自己的需要更改这个模板驱动1、DM9000C的硬件连接 硬件连接图如下所示:它接在S3C2440的BANK4内存控制器上,它只占用8个字节的长度,并且是16bit的位宽。 下面介绍一下DM9000C的主要引脚的功能:SD0-S…

Linux网络驱动--snull

snull是《Linux Device Drivers》中的一个网络驱动的例子。这里引用这个例子学习Linux网络驱动。 因为snull的源码,网上已经更新到适合最新内核,而我自己用的还是2.6.22.6比较旧的内核。而网上好像找不到旧版的snull。因此结合《Linux Device Drivers》把最新的snull例子移植…

在数据驱动下机械故障诊断的一些方法

机械故障是风力发电设备、航空发动机、高档数控机床等大型机械装备安全可靠运行的“潜在杀手”。故障诊断是保障机械装备安全运行的“杀手锏”。由于诊断的装备量大面广、每台装备测点多、数据采样频率高、装备服役历时长&#xff0c;所以 获取了海量的诊断数据&#xff0c;推动…

OPENWRT MT7628 驱动移植WIFI折腾记

本人所写的博客都为开发之中遇到问题记录的随笔,主要是给自己积累些问题。免日后无印象,如有不当之处敬请指正(欢迎进扣群 24849632 探讨问题),如需转载,请复制全部内容包括此行; 我手上的MT7628开发板编译后,没有无线接口,检查menuconfig后,发现MT7628需要选中kmod…

【Linux 菜鸡中心】linux 驱动模块卸载, rmmod 报错 “Segmentation fault (core dumped)”

【Linux 菜鸡中心】驱动模块卸载&#xff0c;rmmod 报错 “Segmentation fault (core dumped)” 【引子】开此专栏主要记录&#xff0c;Linux开发过程中遇到的各种菜鸡问题&#xff0c;常执鞭大笑以策之。 【菜鸡简述】&#xff1a;写一个linux驱动模块时&#xff0c;insmod正常…