以下是我的一个利用SPI控制器操作屏的一个操作实例 包含一个bpeer_tft.c 和一个bpeer_tft.h
这是我基于flash驱动剥离出来的spi控制器驱动
好的话,顶起来~~~~~~~~~~~~~~~~~~~
下面是代码:
bpeer_tft.c
1 /* 2 * MTD SPI driver for ST M25Pxx flash chips 3 * 4 * Author: Mike Lavender, [email protected] 5 * 6 * Copyright (c) 2005, Intec Automation Inc. 7 * 8 * Some parts are based on lart.c by Abraham Van Der Merwe 9 * 10 * Cleaned up and generalized based on mtd_dataflash.c 11 * 12 * This code is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License version 2 as 14 * 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 #else 36 #include "ralink_spi.h" 37 #endif 38 #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_DEBUG 57 #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 #else 64 #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);
如有疑问,请指出,多多交流