📄 sspscreen.c
字号:
#include <linux/module.h>#include <linux/autoconf.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/spinlock.h>#include <linux/proc_fs.h>#include <linux/sysctl.h>#include <linux/interrupt.h>#include <asm/uaccess.h>#include <asm/arch/hardware.h>#include <asm/arch/pxa-regs.h>#include <asm/arch/ssp.h>#include <asm/arch/irqs.h>#include <asm/errno.h>#include "sspscreen.h"#define DEVICE_NAME "screen"#define SCREEN_BAUD (0x001 << 8)#define DSS_9 8#define FRF_SPI 0#define SSE_ENABLED (1 << 7)#define SPO (1 << 3)#define SPH (1 << 4)//**********************************************************************// NSSP lines and GPIOsstatic int gNSSPClk = 81; //NSSP_CLOCKstatic int gNSSPCS = 82; //NSSP_FRAMEstatic int gNSSPData = 83; //NSSP_TXD MOSIstatic int gGPIOReset = 84; //NSSP_RXD MISOstruct ssp_dev gSpiDevice;//**********************************************************************// DELAYstatic void screen_delay(int n){ int time_to_stop = get_jiffies_64() + n; int time_now; do { time_now = get_jiffies_64(); cpu_relax(); //printk("n: %d now: %d stop: %d\n", n, time_now, time_to_stop); }while(time_now < time_to_stop);}//**********************************************************************// SET/CLEARstatic void set_gpio(int gpio){ GPSR(gpio) = GPIO_bit(gpio);}static void clear_gpio(int gpio){ GPCR(gpio) = GPIO_bit(gpio);}//**********************************************************************// SEND BIT/DATA/COMMANDvoid send_cmd(unsigned char b){ int value; u32 readOut; readOut=0; value = b; // Write data ssp_write_word(&gSpiDevice, value); // Read to keep SPI happy! ssp_read_word(&gSpiDevice, &readOut);}void send_data(unsigned char b){ int value; u32 readOut; readOut=0; value = b | 0x100; // Write data ssp_write_word(&gSpiDevice, value); // Read to keep SPI happy! ssp_read_word(&gSpiDevice,&readOut);}//**********************************************************************// PUT PIXELvoid put_pixel(unsigned char color, unsigned char x, unsigned char y){ send_cmd(PASET); // page start/end ram send_data(x);// for some reason starts at 2 send_data(x + 1); send_cmd(CASET); // column start/end ram send_data(y); // for some reason starts at 2 send_data(y + 1); send_cmd(RAMWR); // write something send_data(color);}//**********************************************************************// FILE OPERATIONSstruct file_operations screen_fops ={ owner: THIS_MODULE,// ioctl: whatever,// open: jogwheel_open,// release: jogwheel_release,// read: jogwheel_read,};//**********************************************************************// INITstatic int __init screen_init( void ){ int rc; int i; int speed = SCREEN_BAUD; int mode = DSS_9 | FRF_SPI | SSE_ENABLED; int flags = SPO | SPH; int result=0; printk("screen: init called\n"); // register our device with Linux if (( rc = register_chrdev( SCREEN_MAJOR, DEVICE_NAME, &screen_fops )) < 0 ) { printk( KERN_WARNING "screen: register_chrdev failed for major %d\n", SCREEN_MAJOR ); return rc; } printk("screen: init GPIO pins\n"); // Pin functions and directions pxa_gpio_mode( gNSSPData | GPIO_ALT_FN_1_OUT ); pxa_gpio_mode( gNSSPClk | GPIO_ALT_FN_1_OUT ); pxa_gpio_mode( gNSSPCS | GPIO_ALT_FN_1_OUT ); pxa_gpio_mode( gGPIOReset | GPIO_OUT ); // Setup GPIO levels set_gpio(gGPIOReset); printk("screen: init NSSP\n"); result=ssp_init(&gSpiDevice, 2,flags); if (result) { printk("ssp_init() failed!\n"); } printk("ssp_init() success!%d\n",result); /* configure NSSP port parameters */ ssp_config(&gSpiDevice, mode, flags, 0, speed); ssp_enable(&gSpiDevice); printk("screen: display reset\n"); // Reset the display clear_gpio(gGPIOReset); screen_delay(10); set_gpio(gGPIOReset); screen_delay(10); printk("screen: display reset : control\n"); // display control send_cmd(DISCTL); printk("screen: display reset : send_cmd(DISCTL)\n"); send_data(0x03); printk("screen: display reset : d1\n"); send_data(0x20); printk("screen: display reset : d2\n"); send_data(0x0C); //send_data(0x00); // EH? printk("screen: display reset : comscn\n"); // comscn send_cmd(COMSCN); send_data(0x01); printk("screen: display reset : oscon\n"); // oscon send_cmd(OSCON); // sleep out printk("screen: sleep out\n"); send_cmd(SLPOUT); screen_delay(10); // electronic volume, this is kinda contrast/brightness // this might be different for individual LCDs send_cmd(VOLCTR); send_data(0x05); send_data(0x01); send_cmd(VOLDOWN); send_cmd(VOLDOWN); send_cmd(TMPGRD); send_data(0); send_data(0); send_data(0); send_data(0); send_data(0); // power ctrl //everything on, no external reference resistors send_cmd(PWRCTR); send_data(0x0f); screen_delay(10); //send_cmd(PTLOUT); //send_cmd(RMWOUT); // Scroll area //send_cmd(ASCSET); //send_data(0x00); //send_data(0x00); //send_data(0x00); //send_data(0x03); // Whole screen //send_cmd(SCSTART); //send_data(0x00); // display mode send_cmd(DISINV); // datctl send_cmd(DATCTL); send_data(0x00); send_data(0x00); send_data(0x01); printk("screen: color LUT\n"); // setup color lookup table send_cmd(RGBSET8); // color table //RED send_data(0); send_data(2); send_data(4); send_data(6); send_data(8); send_data(10); send_data(12); send_data(15); // GREEN send_data(0); send_data(2); send_data(4); send_data(6); send_data(8); send_data(10); send_data(12); send_data(15); //BLUE send_data(0); send_data(4); send_data(9); send_data(15); // nop send_cmd(NOP); // display on screen_delay(100); printk("screen: display on\n"); send_cmd(DISON); screen_delay(10); // this loop adjusts the contrast, change the number of iterations to get // desired contrast. this might be different for individual LCDs printk("screen: contrast loop\n"); for (i = 0; i < 50; i++) { send_cmd(VOLUP); } // page start/end ram send_cmd(PASET); // for some reason starts at 2 send_data(0x00); send_data(0x83); // column start/end ram send_cmd(CASET); send_data(0x00); send_data(0x83); // write some stuff (background) send_cmd(RAMWR); for (i = 0; i < 17424; i++) { if(i % 200 == 0) printk("screen: background: %d\r", i); send_data(i % 0x100); //if(i == 200) // send_data(0xE0); // 1C is green E0 is red 03 is blue //else if(i % 3 == 1) // send_data(0x1C); // 1C is green E0 is red 03 is blue //else // send_data(0x03); // 1C is green E0 is red 03 is blue } printk("screen: background: %d\n", i); // draw a multi-colored square in the center of screen int x, y, c; for (i = 0; i < 4096; i++) { if(i % 50 == 0) printk("screen: square: %d\r", i); x = (i % 64) + 32; y = (i / 64) + 32; if(x <= 63 && y <= 63) c = 0xE0; else if(x > 63 && y <= 63) c = 0x1C; else if(x <= 63 && y > 63) c = 0x03; else c = 0xE3; put_pixel(c, x, y); } printk("screen: square: %d\n", i); return 0;}//**********************************************************************// EXITstatic void __exit screen_exit( void ){ printk("screen: exit called\n"); send_cmd(SLPIN); screen_delay(10); send_cmd(DISOFF); screen_delay(10); ssp_exit(&gSpiDevice); unregister_chrdev( SCREEN_MAJOR, DEVICE_NAME );}//**********************************************************************// MODULE SETUPmodule_init(screen_init);module_exit(screen_exit);MODULE_AUTHOR("Dan Taylor");MODULE_DESCRIPTION("Screen Driver");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -