0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013
0014 #include <linux/init.h>
0015 #include <linux/module.h>
0016 #include <linux/kernel.h>
0017 #include <linux/delay.h>
0018 #include <linux/parport.h>
0019 #include <linux/ks0108.h>
0020
0021 #define KS0108_NAME "ks0108"
0022
0023
0024
0025
0026
0027 static unsigned int ks0108_port = CONFIG_KS0108_PORT;
0028 module_param(ks0108_port, uint, 0444);
0029 MODULE_PARM_DESC(ks0108_port, "Parallel port where the LCD is connected");
0030
0031 static unsigned int ks0108_delay = CONFIG_KS0108_DELAY;
0032 module_param(ks0108_delay, uint, 0444);
0033 MODULE_PARM_DESC(ks0108_delay, "Delay between each control writing (microseconds)");
0034
0035
0036
0037
0038
0039 static struct parport *ks0108_parport;
0040 static struct pardevice *ks0108_pardevice;
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 #define bit(n) (((unsigned char)1)<<(n))
0059
0060 void ks0108_writedata(unsigned char byte)
0061 {
0062 parport_write_data(ks0108_parport, byte);
0063 }
0064
0065 void ks0108_writecontrol(unsigned char byte)
0066 {
0067 udelay(ks0108_delay);
0068 parport_write_control(ks0108_parport, byte ^ (bit(0) | bit(1) | bit(3)));
0069 }
0070
0071 void ks0108_displaystate(unsigned char state)
0072 {
0073 ks0108_writedata((state ? bit(0) : 0) | bit(1) | bit(2) | bit(3) | bit(4) | bit(5));
0074 }
0075
0076 void ks0108_startline(unsigned char startline)
0077 {
0078 ks0108_writedata(min_t(unsigned char, startline, 63) | bit(6) |
0079 bit(7));
0080 }
0081
0082 void ks0108_address(unsigned char address)
0083 {
0084 ks0108_writedata(min_t(unsigned char, address, 63) | bit(6));
0085 }
0086
0087 void ks0108_page(unsigned char page)
0088 {
0089 ks0108_writedata(min_t(unsigned char, page, 7) | bit(3) | bit(4) |
0090 bit(5) | bit(7));
0091 }
0092
0093 EXPORT_SYMBOL_GPL(ks0108_writedata);
0094 EXPORT_SYMBOL_GPL(ks0108_writecontrol);
0095 EXPORT_SYMBOL_GPL(ks0108_displaystate);
0096 EXPORT_SYMBOL_GPL(ks0108_startline);
0097 EXPORT_SYMBOL_GPL(ks0108_address);
0098 EXPORT_SYMBOL_GPL(ks0108_page);
0099
0100
0101
0102
0103
0104 static unsigned char ks0108_inited;
0105 unsigned char ks0108_isinited(void)
0106 {
0107 return ks0108_inited;
0108 }
0109 EXPORT_SYMBOL_GPL(ks0108_isinited);
0110
0111 static void ks0108_parport_attach(struct parport *port)
0112 {
0113 struct pardev_cb ks0108_cb;
0114
0115 if (port->base != ks0108_port)
0116 return;
0117
0118 memset(&ks0108_cb, 0, sizeof(ks0108_cb));
0119 ks0108_cb.flags = PARPORT_DEV_EXCL;
0120 ks0108_pardevice = parport_register_dev_model(port, KS0108_NAME,
0121 &ks0108_cb, 0);
0122 if (!ks0108_pardevice) {
0123 pr_err("ERROR: parport didn't register new device\n");
0124 return;
0125 }
0126 if (parport_claim(ks0108_pardevice)) {
0127 pr_err("could not claim access to parport %i. Aborting.\n",
0128 ks0108_port);
0129 goto err_unreg_device;
0130 }
0131
0132 ks0108_parport = port;
0133 ks0108_inited = 1;
0134 return;
0135
0136 err_unreg_device:
0137 parport_unregister_device(ks0108_pardevice);
0138 ks0108_pardevice = NULL;
0139 }
0140
0141 static void ks0108_parport_detach(struct parport *port)
0142 {
0143 if (port->base != ks0108_port)
0144 return;
0145
0146 if (!ks0108_pardevice) {
0147 pr_err("%s: already unregistered.\n", KS0108_NAME);
0148 return;
0149 }
0150
0151 parport_release(ks0108_pardevice);
0152 parport_unregister_device(ks0108_pardevice);
0153 ks0108_pardevice = NULL;
0154 ks0108_parport = NULL;
0155 }
0156
0157
0158
0159
0160
0161 static struct parport_driver ks0108_parport_driver = {
0162 .name = "ks0108",
0163 .match_port = ks0108_parport_attach,
0164 .detach = ks0108_parport_detach,
0165 .devmodel = true,
0166 };
0167 module_parport_driver(ks0108_parport_driver);
0168
0169 MODULE_LICENSE("GPL v2");
0170 MODULE_AUTHOR("Miguel Ojeda <ojeda@kernel.org>");
0171 MODULE_DESCRIPTION("ks0108 LCD Controller driver");
0172