以下是我的一个利用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
如有疑问,请指出,多多交流