ks0108.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Filename: ks0108.c
  3. * Version: 0.1.0
  4. * Description: ks0108 LCD Controller driver
  5. * License: GPLv2
  6. * Depends: parport
  7. *
  8. * Author: Copyright (C) Miguel Ojeda Sandonis
  9. * Date: 2006-10-31
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License version 2 as
  13. * published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. */
  25. #include <linux/init.h>
  26. #include <linux/module.h>
  27. #include <linux/kernel.h>
  28. #include <linux/delay.h>
  29. #include <linux/fs.h>
  30. #include <linux/io.h>
  31. #include <linux/parport.h>
  32. #include <linux/uaccess.h>
  33. #include <linux/ks0108.h>
  34. #define KS0108_NAME "ks0108"
  35. /*
  36. * Module Parameters
  37. */
  38. static unsigned int ks0108_port = CONFIG_KS0108_PORT;
  39. module_param(ks0108_port, uint, S_IRUGO);
  40. MODULE_PARM_DESC(ks0108_port, "Parallel port where the LCD is connected");
  41. static unsigned int ks0108_delay = CONFIG_KS0108_DELAY;
  42. module_param(ks0108_delay, uint, S_IRUGO);
  43. MODULE_PARM_DESC(ks0108_delay, "Delay between each control writing (microseconds)");
  44. /*
  45. * Device
  46. */
  47. static struct parport *ks0108_parport;
  48. static struct pardevice *ks0108_pardevice;
  49. /*
  50. * ks0108 Exported Commands (don't lock)
  51. *
  52. * You _should_ lock in the top driver: This functions _should not_
  53. * get race conditions in any way. Locking for each byte here would be
  54. * so slow and useless.
  55. *
  56. * There are not bit definitions because they are not flags,
  57. * just arbitrary combinations defined by the documentation for each
  58. * function in the ks0108 LCD controller. If you want to know what means
  59. * a specific combination, look at the function's name.
  60. *
  61. * The ks0108_writecontrol bits need to be reverted ^(0,1,3) because
  62. * the parallel port also revert them using a "not" logic gate.
  63. */
  64. #define bit(n) (((unsigned char)1)<<(n))
  65. void ks0108_writedata(unsigned char byte)
  66. {
  67. parport_write_data(ks0108_parport, byte);
  68. }
  69. void ks0108_writecontrol(unsigned char byte)
  70. {
  71. udelay(ks0108_delay);
  72. parport_write_control(ks0108_parport, byte ^ (bit(0) | bit(1) | bit(3)));
  73. }
  74. void ks0108_displaystate(unsigned char state)
  75. {
  76. ks0108_writedata((state ? bit(0) : 0) | bit(1) | bit(2) | bit(3) | bit(4) | bit(5));
  77. }
  78. void ks0108_startline(unsigned char startline)
  79. {
  80. ks0108_writedata(min(startline,(unsigned char)63) | bit(6) | bit(7));
  81. }
  82. void ks0108_address(unsigned char address)
  83. {
  84. ks0108_writedata(min(address,(unsigned char)63) | bit(6));
  85. }
  86. void ks0108_page(unsigned char page)
  87. {
  88. ks0108_writedata(min(page,(unsigned char)7) | bit(3) | bit(4) | bit(5) | bit(7));
  89. }
  90. EXPORT_SYMBOL_GPL(ks0108_writedata);
  91. EXPORT_SYMBOL_GPL(ks0108_writecontrol);
  92. EXPORT_SYMBOL_GPL(ks0108_displaystate);
  93. EXPORT_SYMBOL_GPL(ks0108_startline);
  94. EXPORT_SYMBOL_GPL(ks0108_address);
  95. EXPORT_SYMBOL_GPL(ks0108_page);
  96. /*
  97. * Is the module inited?
  98. */
  99. static unsigned char ks0108_inited;
  100. unsigned char ks0108_isinited(void)
  101. {
  102. return ks0108_inited;
  103. }
  104. EXPORT_SYMBOL_GPL(ks0108_isinited);
  105. /*
  106. * Module Init & Exit
  107. */
  108. static int __init ks0108_init(void)
  109. {
  110. int result;
  111. int ret = -EINVAL;
  112. ks0108_parport = parport_find_base(ks0108_port);
  113. if (ks0108_parport == NULL) {
  114. printk(KERN_ERR KS0108_NAME ": ERROR: "
  115. "parport didn't find %i port\n", ks0108_port);
  116. goto none;
  117. }
  118. ks0108_pardevice = parport_register_device(ks0108_parport, KS0108_NAME,
  119. NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
  120. if (ks0108_pardevice == NULL) {
  121. printk(KERN_ERR KS0108_NAME ": ERROR: "
  122. "parport didn't register new device\n");
  123. goto none;
  124. }
  125. result = parport_claim(ks0108_pardevice);
  126. if (result != 0) {
  127. printk(KERN_ERR KS0108_NAME ": ERROR: "
  128. "can't claim %i parport, maybe in use\n", ks0108_port);
  129. ret = result;
  130. goto registered;
  131. }
  132. ks0108_inited = 1;
  133. return 0;
  134. registered:
  135. parport_unregister_device(ks0108_pardevice);
  136. none:
  137. return ret;
  138. }
  139. static void __exit ks0108_exit(void)
  140. {
  141. parport_release(ks0108_pardevice);
  142. parport_unregister_device(ks0108_pardevice);
  143. }
  144. module_init(ks0108_init);
  145. module_exit(ks0108_exit);
  146. MODULE_LICENSE("GPL v2");
  147. MODULE_AUTHOR("Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>");
  148. MODULE_DESCRIPTION("ks0108 LCD Controller driver");