0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/module.h>
0018 #include <linux/init.h>
0019 #include <linux/parport.h>
0020 #include <linux/ioport.h>
0021 #include <linux/interrupt.h>
0022 #include <linux/platform_device.h>
0023
0024 #include <asm/setup.h>
0025 #include <asm/amigahw.h>
0026 #include <asm/irq.h>
0027 #include <asm/io.h>
0028 #include <asm/amigaints.h>
0029
0030 #undef DEBUG
0031
0032 static void amiga_write_data(struct parport *p, unsigned char data)
0033 {
0034 pr_debug("write_data %c\n", data);
0035
0036 ciaa.prb = data;
0037 mb();
0038 }
0039
0040 static unsigned char amiga_read_data(struct parport *p)
0041 {
0042
0043 return ciaa.prb;
0044 }
0045
0046 static unsigned char control_amiga_to_pc(unsigned char control)
0047 {
0048 return PARPORT_CONTROL_SELECT |
0049 PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE;
0050
0051
0052 }
0053
0054 static void amiga_write_control(struct parport *p, unsigned char control)
0055 {
0056 pr_debug("write_control %02x\n", control);
0057
0058 }
0059
0060 static unsigned char amiga_read_control( struct parport *p)
0061 {
0062 pr_debug("read_control\n");
0063 return control_amiga_to_pc(0);
0064 }
0065
0066 static unsigned char amiga_frob_control( struct parport *p, unsigned char mask, unsigned char val)
0067 {
0068 unsigned char old;
0069
0070 pr_debug("frob_control mask %02x, value %02x\n", mask, val);
0071 old = amiga_read_control(p);
0072 amiga_write_control(p, (old & ~mask) ^ val);
0073 return old;
0074 }
0075
0076 static unsigned char status_amiga_to_pc(unsigned char status)
0077 {
0078 unsigned char ret = PARPORT_STATUS_BUSY | PARPORT_STATUS_ACK | PARPORT_STATUS_ERROR;
0079
0080 if (status & 1)
0081 ret &= ~PARPORT_STATUS_BUSY;
0082 if (status & 2)
0083 ret |= PARPORT_STATUS_PAPEROUT;
0084 if (status & 4)
0085 ret |= PARPORT_STATUS_SELECT;
0086
0087
0088 return ret;
0089 }
0090
0091 static unsigned char amiga_read_status(struct parport *p)
0092 {
0093 unsigned char status;
0094
0095 status = status_amiga_to_pc(ciab.pra & 7);
0096 pr_debug("read_status %02x\n", status);
0097 return status;
0098 }
0099
0100 static void amiga_enable_irq(struct parport *p)
0101 {
0102 enable_irq(IRQ_AMIGA_CIAA_FLG);
0103 }
0104
0105 static void amiga_disable_irq(struct parport *p)
0106 {
0107 disable_irq(IRQ_AMIGA_CIAA_FLG);
0108 }
0109
0110 static void amiga_data_forward(struct parport *p)
0111 {
0112 pr_debug("forward\n");
0113 ciaa.ddrb = 0xff;
0114 mb();
0115 }
0116
0117 static void amiga_data_reverse(struct parport *p)
0118 {
0119 pr_debug("reverse\n");
0120 ciaa.ddrb = 0;
0121 mb();
0122 }
0123
0124 static void amiga_init_state(struct pardevice *dev, struct parport_state *s)
0125 {
0126 s->u.amiga.data = 0;
0127 s->u.amiga.datadir = 255;
0128 s->u.amiga.status = 0;
0129 s->u.amiga.statusdir = 0;
0130 }
0131
0132 static void amiga_save_state(struct parport *p, struct parport_state *s)
0133 {
0134 mb();
0135 s->u.amiga.data = ciaa.prb;
0136 s->u.amiga.datadir = ciaa.ddrb;
0137 s->u.amiga.status = ciab.pra & 7;
0138 s->u.amiga.statusdir = ciab.ddra & 7;
0139 mb();
0140 }
0141
0142 static void amiga_restore_state(struct parport *p, struct parport_state *s)
0143 {
0144 mb();
0145 ciaa.prb = s->u.amiga.data;
0146 ciaa.ddrb = s->u.amiga.datadir;
0147 ciab.pra |= (ciab.pra & 0xf8) | s->u.amiga.status;
0148 ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
0149 mb();
0150 }
0151
0152 static struct parport_operations pp_amiga_ops = {
0153 .write_data = amiga_write_data,
0154 .read_data = amiga_read_data,
0155
0156 .write_control = amiga_write_control,
0157 .read_control = amiga_read_control,
0158 .frob_control = amiga_frob_control,
0159
0160 .read_status = amiga_read_status,
0161
0162 .enable_irq = amiga_enable_irq,
0163 .disable_irq = amiga_disable_irq,
0164
0165 .data_forward = amiga_data_forward,
0166 .data_reverse = amiga_data_reverse,
0167
0168 .init_state = amiga_init_state,
0169 .save_state = amiga_save_state,
0170 .restore_state = amiga_restore_state,
0171
0172 .epp_write_data = parport_ieee1284_epp_write_data,
0173 .epp_read_data = parport_ieee1284_epp_read_data,
0174 .epp_write_addr = parport_ieee1284_epp_write_addr,
0175 .epp_read_addr = parport_ieee1284_epp_read_addr,
0176
0177 .ecp_write_data = parport_ieee1284_ecp_write_data,
0178 .ecp_read_data = parport_ieee1284_ecp_read_data,
0179 .ecp_write_addr = parport_ieee1284_ecp_write_addr,
0180
0181 .compat_write_data = parport_ieee1284_write_compat,
0182 .nibble_read_data = parport_ieee1284_read_nibble,
0183 .byte_read_data = parport_ieee1284_read_byte,
0184
0185 .owner = THIS_MODULE,
0186 };
0187
0188
0189
0190 static int __init amiga_parallel_probe(struct platform_device *pdev)
0191 {
0192 struct parport *p;
0193 int err;
0194
0195 ciaa.ddrb = 0xff;
0196 ciab.ddra &= 0xf8;
0197 mb();
0198
0199 p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG,
0200 PARPORT_DMA_NONE, &pp_amiga_ops);
0201 if (!p)
0202 return -EBUSY;
0203
0204 err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name,
0205 p);
0206 if (err)
0207 goto out_irq;
0208
0209 pr_info("%s: Amiga built-in port using irq\n", p->name);
0210
0211 parport_announce_port(p);
0212
0213 platform_set_drvdata(pdev, p);
0214
0215 return 0;
0216
0217 out_irq:
0218 parport_put_port(p);
0219 return err;
0220 }
0221
0222 static int __exit amiga_parallel_remove(struct platform_device *pdev)
0223 {
0224 struct parport *port = platform_get_drvdata(pdev);
0225
0226 parport_remove_port(port);
0227 if (port->irq != PARPORT_IRQ_NONE)
0228 free_irq(IRQ_AMIGA_CIAA_FLG, port);
0229 parport_put_port(port);
0230 return 0;
0231 }
0232
0233 static struct platform_driver amiga_parallel_driver = {
0234 .remove = __exit_p(amiga_parallel_remove),
0235 .driver = {
0236 .name = "amiga-parallel",
0237 },
0238 };
0239
0240 module_platform_driver_probe(amiga_parallel_driver, amiga_parallel_probe);
0241
0242 MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
0243 MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
0244 MODULE_LICENSE("GPL");
0245 MODULE_ALIAS("platform:amiga-parallel");