免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 898 | 回复: 0
打印 上一主题 下一主题

w90x950_12864lcdm [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-23 02:53 |只看该作者 |倒序浏览
  1. /*
  2.  *
  3.  * drivers/w90x950_12864lcdm.c
  4.  *
  5.  * (c) 2010 Adem Zhu<dengbo.zhu@gmail.com>
  6.  *
  7.  * W90x950 128X64 TN LCD pane Model driver
  8.  *
  9. */

  10. #include <linux/module.h>
  11. #include <linux/fs.h>
  12. #include <linux/delay.h>
  13. #include <asm/uaccess.h>

  14. #include <asm/arch/hardware.h>
  15. #include <asm/io.h>

  16. #include <asm/arch/w90x900_reg.h>

  17. #define    LCDM12864_MAJOR            (79)
  18. #define DEV_NAME            "lcdm128x64"

  19. #define LCDM12864_RESET            (0x00)
  20. /* refrest LCDM, no arg */

  21. #define    LCDM12864_REFRESH_BLOCK_IN_PAGE    (0x01)
  22. /* arg is pointer of struct lcdm12864_refresh_block */

  23. struct lcdm12864_refresh_block
  24. {
  25.     unsigned char page;
  26.     unsigned char startx;
  27.     unsigned char endx;
  28.     unsigned char length;
  29.     unsigned char *data;
  30. };

  31. #define LCDM12864_BACKLIGHT_CTRL    (0x02)
  32. /* the LCDM backlight is on when arg is a non-zero value */

  33. /*
  34. hardware definitions.
  35.     LCDM_CS        <=>        GPIO D2
  36.     LCDM_RES    <=>        GPIO D3
  37.     LCDM_A0        <=>        GPIO D0
  38.     LCDM_SCK    <=>        GPIO D5
  39.     LCDM_SDA    <=>        GPIO D6

  40.     LCDM_BACKLIGHT    <=>        GPIO D1
  41. */

  42. static void hw_128X64_sendbyte(unsigned char db)
  43. {
  44.     long value;
  45.     int index;
  46.     for (index = 0; index < 8; index ++)
  47.     {
  48.         value = inl(REG_GPIOD_DATAOUT);
  49.         value &= ~(1<<6);
  50.         if (db & 0x80)
  51.         {
  52.             value |= (1<<6);
  53.         }

  54.         outl(value, REG_GPIOD_DATAOUT);    /* flush LCDM_SDA */

  55.         outl(inl(REG_GPIOD_DATAOUT) & ~(1 << 5), REG_GPIOD_DATAOUT); /*clock down LCDM_SCK (GPIO D5)*/

  56.         db <<= 1;

  57.         outl(inl(REG_GPIOD_DATAOUT) | (1 << 5), REG_GPIOD_DATAOUT); /*clock up LCDM_SCK (GPIO D5)*/
  58.     }
  59. }

  60. static void hw_128X64_init(void)
  61. {
  62.     outl(inl(REG_GPIOD_DATAOUT) | (1 << 5), REG_GPIOD_DATAOUT); /*default: clock up LCDM_SCK (GPIO D5)*/

  63.     outl(inl(REG_GPIOD_DATAOUT) & ~(1 << 0), REG_GPIOD_DATAOUT); /*pull down LCDM_A0 (GPIO D0)*/

  64.     outl(inl(REG_GPIOD_DATAOUT) & ~(1 << 2), REG_GPIOD_DATAOUT); /*pull down LCDM_CS (GPIO D2)*/
  65. }

  66. static void hw_128X64_reset(void) /* Reset the module */
  67. {
  68.     outl(inl(REG_GPIOD_DATAOUT) & ~(1 << 3), REG_GPIOD_DATAOUT); /*pull down LCDM_RES (GPIO D3)*/

  69.     udelay(1000);

  70.     outl(inl(REG_GPIOD_DATAOUT) | (1 << 3), REG_GPIOD_DATAOUT); /*pull up LCDM_RES (GPIO D3)*/

  71.     udelay(1000);
  72. }

  73. static void hw_128X64_open(void)
  74. {
  75.     /* Booster ratio set : 5X */
  76.     hw_128X64_sendbyte(0xf8);
  77.     udelay(999);
  78.     hw_128X64_sendbyte(0x01);
  79.     udelay(999);

  80.     /* Segment Driver Direction Select : Normal */
  81.     hw_128X64_sendbyte(0xa0);
  82.     udelay(999);

  83.     /* Common Output Mode Select : Normal */
  84.     hw_128X64_sendbyte(0xc0);
  85.     udelay(999);

  86.     /* LCD Bias Set : 1/65 duty, 1/9 bias */
  87.     hw_128X64_sendbyte(0xa2);
  88.     udelay(2000);

  89.     /* power control set */
  90.     hw_128X64_sendbyte(0x2c);
  91.     udelay(2000);

  92.     hw_128X64_sendbyte(0x2e);
  93.     udelay(2000);

  94.     hw_128X64_sendbyte(0x2f);
  95.     udelay(2000);

  96.     /* power control set */
  97.     hw_128X64_sendbyte(0x25);
  98.     udelay(999);

  99.     /* The Electronic Volume Mode Set */
  100.     hw_128X64_sendbyte(0x81);
  101.     udelay(999);
  102.     hw_128X64_sendbyte(34);
  103.     udelay(999);

  104.     /* Display all points off */
  105.     hw_128X64_sendbyte(0xa4);
  106.     udelay(999);

  107.     /* Display ON mode */
  108.     hw_128X64_sendbyte(0xaf);
  109.     udelay(999);
  110. }

  111. static void hw_128X64_set_startline(unsigned char start_line)
  112. {
  113.     /* 0 1 Display start address */
  114.     hw_128X64_sendbyte((start_line & 0x3f) | 0x40);
  115. }

  116. static void hw_128X64_set_page(unsigned char page)
  117. {
  118.     /* 1 0 1 1 page address */
  119.     hw_128X64_sendbyte((page & 0x0f) | 0xb0);
  120. }

  121. static void hw_128X64_set_column(unsigned char column)
  122. {
  123.     /* 0 0 0 1 higher bits */
  124.     hw_128X64_sendbyte(((column >> 4) & 0x0f) | 0x10);

  125.     /* 0 0 0 0 lower bits */
  126.     hw_128X64_sendbyte(column & 0x0f);
  127. }

  128. static void hw_128X64_writedata(unsigned char db)
  129. {
  130.     outl(inl(REG_GPIOD_DATAOUT) | (1 << 0), REG_GPIOD_DATAOUT); /*pull up LCDM_A0 (GPIO D0)*/

  131.     /* data */
  132.     hw_128X64_sendbyte(db);

  133.     outl(inl(REG_GPIOD_DATAOUT) & ~(1 << 0), REG_GPIOD_DATAOUT); /*pull down LCDM_A0 (GPIO D0)*/
  134. }

  135. static void lcdm_reset(void) /* reset lcd model : init & reset & open & set_startline */
  136. {
  137.     hw_128X64_init();

  138.     hw_128X64_reset();

  139.     hw_128X64_open();

  140.     hw_128X64_set_startline(0);
  141. }

  142. static void lcdm_refresh_block_in_page(unsigned char page, unsigned char startx, unsigned char endx, char * data)
  143. {
  144.     int cnt = (endx - startx + 1);

  145.     hw_128X64_set_page(page);

  146.     hw_128X64_set_column(startx);

  147.     for (;cnt--;)
  148.     {
  149.         hw_128X64_writedata(*data ++);
  150.     }
  151. }

  152. static int w90x950_12864lcdm_open(struct inode *inode, struct file *file)
  153. {
  154.     return 0;
  155. }

  156. static int w90x950_12864lcdm_close(struct inode *inode, struct file *file)
  157. {
  158.     return 0;
  159. }

  160. static int w90x950_12864lcdm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  161. {
  162.     struct lcdm12864_refresh_block refresh_cmd;
  163.     unsigned char *buf;

  164.     switch (cmd)
  165.     {
  166.         case LCDM12864_RESET: /* reset lcd module */
  167.             lcdm_reset();
  168.             return 0;
  169.             break;

  170.         case LCDM12864_REFRESH_BLOCK_IN_PAGE:
  171.             if (!arg)
  172.                 return -EINVAL;

  173.             if (copy_from_user(&refresh_cmd, (const void *)arg, sizeof(struct lcdm12864_refresh_block)))
  174.                 return -EFAULT;

  175.             if (refresh_cmd.length != refresh_cmd.endx - refresh_cmd.startx + 1)
  176.                 return -EINVAL;

  177.             /* allocate memory */
  178.             buf = kzalloc(refresh_cmd.length, GFP_KERNEL);
  179.             if (!buf)
  180.                 return -ENOMEM;

  181.             if (copy_from_user(buf, refresh_cmd.data, refresh_cmd.length))
  182.             {
  183.                 kfree(buf);
  184.                 return -EFAULT;
  185.             }

  186.             lcdm_refresh_block_in_page(refresh_cmd.page, refresh_cmd.startx, refresh_cmd.endx, refresh_cmd.data);

  187.             kfree(buf);
  188.             return 0;
  189.             break;

  190.         case LCDM12864_BACKLIGHT_CTRL:
  191.             if (arg)
  192.             {
  193.                 outl(inl(REG_GPIOD_DATAOUT) | (1 << 1), REG_GPIOD_DATAOUT); /*pull up LCDM_BACKLIGHT (GPIO D1)*/
  194.             }
  195.             else
  196.             {
  197.                 outl(inl(REG_GPIOD_DATAOUT) & ~(1 << 1), REG_GPIOD_DATAOUT); /*pull down LCDM_BACKLIGHT (GPIO D1)*/
  198.             };
  199.             return 0;
  200.             break;
  201.     }

  202.     return -EINVAL;
  203. }

  204. struct file_operations w90x950_12864lcdm_fops =
  205. {
  206.     owner:      THIS_MODULE,
  207.     open:     w90x950_12864lcdm_open,
  208.     ioctl:     w90x950_12864lcdm_ioctl,
  209.     release: w90x950_12864lcdm_close,
  210. };

  211. static int __init w90x950_12864lcdm_init(void)
  212. {
  213.     if (register_chrdev(LCDM12864_MAJOR, DEV_NAME, &w90x950_12864lcdm_fops) < 0)
  214.     {
  215.         printk("can't get major %d\n", LCDM12864_MAJOR);
  216.         return -1;
  217.     }

  218.     /* config the all io pins (D0, D1, D2, D3, D5, D6) */
  219.     outl(inl(REG_MFSEL) & ~0x00f0, REG_MFSEL);        /* configure GPIOD to IO function. */
  220.     outl(inl(REG_GPIOD_DIR) | 0x006f, REG_GPIOD_DIR);    /* configure output pins. */
  221.     outl(inl(REG_GPIODPE) | 0x006f, REG_GPIODPE);        /* configure pins as pullup. */

  222.     lcdm_reset();

  223.     printk("W90X950 128X64 TN LCDM driver started successfully!\n");

  224.     return(0);
  225. }

  226. static void __exit w90x950_12864lcdm_exit(void)
  227. {
  228.     unregister_chrdev(LCDM12864_MAJOR, DEV_NAME);
  229. }

  230. module_init(w90x950_12864lcdm_init);
  231. module_exit(w90x950_12864lcdm_exit);

  232. MODULE_AUTHOR("Adem Zhu <dengbo.zhu@gmail.com>");
  233. MODULE_DESCRIPTION("NUC950 128X64 TN LCD pane Model driver");
  234. MODULE_LICENSE("GPL");
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP