1 /* linux/drivers/parport/parport_ax88796.c
3 * (c) 2005,2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/parport.h>
15 #include <linux/interrupt.h>
16 #include <linux/errno.h>
17 #include <linux/platform_device.h>
22 #define AX_SPR_BUSY (1<<7)
23 #define AX_SPR_ACK (1<<6)
24 #define AX_SPR_PE (1<<5)
25 #define AX_SPR_SLCT (1<<4)
26 #define AX_SPR_ERR (1<<3)
28 #define AX_CPR_nDOE (1<<5)
29 #define AX_CPR_SLCTIN (1<<3)
30 #define AX_CPR_nINIT (1<<2)
31 #define AX_CPR_ATFD (1<<1)
32 #define AX_CPR_STRB (1<<0)
35 struct parport
*parport
;
36 struct parport_state suspend
;
41 unsigned char irq_enabled
;
44 void __iomem
*spp_data
;
45 void __iomem
*spp_spr
;
46 void __iomem
*spp_cpr
;
49 static inline struct ax_drvdata
*pp_to_drv(struct parport
*p
)
51 return p
->private_data
;
55 parport_ax88796_read_data(struct parport
*p
)
57 struct ax_drvdata
*dd
= pp_to_drv(p
);
59 return readb(dd
->spp_data
);
63 parport_ax88796_write_data(struct parport
*p
, unsigned char data
)
65 struct ax_drvdata
*dd
= pp_to_drv(p
);
67 writeb(data
, dd
->spp_data
);
71 parport_ax88796_read_control(struct parport
*p
)
73 struct ax_drvdata
*dd
= pp_to_drv(p
);
74 unsigned int cpr
= readb(dd
->spp_cpr
);
77 if (!(cpr
& AX_CPR_STRB
))
78 ret
|= PARPORT_CONTROL_STROBE
;
80 if (!(cpr
& AX_CPR_ATFD
))
81 ret
|= PARPORT_CONTROL_AUTOFD
;
83 if (cpr
& AX_CPR_nINIT
)
84 ret
|= PARPORT_CONTROL_INIT
;
86 if (!(cpr
& AX_CPR_SLCTIN
))
87 ret
|= PARPORT_CONTROL_SELECT
;
93 parport_ax88796_write_control(struct parport
*p
, unsigned char control
)
95 struct ax_drvdata
*dd
= pp_to_drv(p
);
96 unsigned int cpr
= readb(dd
->spp_cpr
);
100 if (!(control
& PARPORT_CONTROL_STROBE
))
103 if (!(control
& PARPORT_CONTROL_AUTOFD
))
106 if (control
& PARPORT_CONTROL_INIT
)
109 if (!(control
& PARPORT_CONTROL_SELECT
))
110 cpr
|= AX_CPR_SLCTIN
;
112 dev_dbg(dd
->dev
, "write_control: ctrl=%02x, cpr=%02x\n", control
, cpr
);
113 writeb(cpr
, dd
->spp_cpr
);
115 if (parport_ax88796_read_control(p
) != control
) {
116 dev_err(dd
->dev
, "write_control: read != set (%02x, %02x)\n",
117 parport_ax88796_read_control(p
), control
);
122 parport_ax88796_read_status(struct parport
*p
)
124 struct ax_drvdata
*dd
= pp_to_drv(p
);
125 unsigned int status
= readb(dd
->spp_spr
);
126 unsigned int ret
= 0;
128 if (status
& AX_SPR_BUSY
)
129 ret
|= PARPORT_STATUS_BUSY
;
131 if (status
& AX_SPR_ACK
)
132 ret
|= PARPORT_STATUS_ACK
;
134 if (status
& AX_SPR_ERR
)
135 ret
|= PARPORT_STATUS_ERROR
;
137 if (status
& AX_SPR_SLCT
)
138 ret
|= PARPORT_STATUS_SELECT
;
140 if (status
& AX_SPR_PE
)
141 ret
|= PARPORT_STATUS_PAPEROUT
;
147 parport_ax88796_frob_control(struct parport
*p
, unsigned char mask
,
150 struct ax_drvdata
*dd
= pp_to_drv(p
);
151 unsigned char old
= parport_ax88796_read_control(p
);
153 dev_dbg(dd
->dev
, "frob: mask=%02x, val=%02x, old=%02x\n",
156 parport_ax88796_write_control(p
, (old
& ~mask
) | val
);
161 parport_ax88796_enable_irq(struct parport
*p
)
163 struct ax_drvdata
*dd
= pp_to_drv(p
);
166 local_irq_save(flags
);
167 if (!dd
->irq_enabled
) {
171 local_irq_restore(flags
);
175 parport_ax88796_disable_irq(struct parport
*p
)
177 struct ax_drvdata
*dd
= pp_to_drv(p
);
180 local_irq_save(flags
);
181 if (dd
->irq_enabled
) {
185 local_irq_restore(flags
);
189 parport_ax88796_data_forward(struct parport
*p
)
191 struct ax_drvdata
*dd
= pp_to_drv(p
);
192 void __iomem
*cpr
= dd
->spp_cpr
;
194 writeb((readb(cpr
) & ~AX_CPR_nDOE
), cpr
);
198 parport_ax88796_data_reverse(struct parport
*p
)
200 struct ax_drvdata
*dd
= pp_to_drv(p
);
201 void __iomem
*cpr
= dd
->spp_cpr
;
203 writeb(readb(cpr
) | AX_CPR_nDOE
, cpr
);
207 parport_ax88796_init_state(struct pardevice
*d
, struct parport_state
*s
)
209 struct ax_drvdata
*dd
= pp_to_drv(d
->port
);
211 memset(s
, 0, sizeof(struct parport_state
));
213 dev_dbg(dd
->dev
, "init_state: %p: state=%p\n", d
, s
);
214 s
->u
.ax88796
.cpr
= readb(dd
->spp_cpr
);
218 parport_ax88796_save_state(struct parport
*p
, struct parport_state
*s
)
220 struct ax_drvdata
*dd
= pp_to_drv(p
);
222 dev_dbg(dd
->dev
, "save_state: %p: state=%p\n", p
, s
);
223 s
->u
.ax88796
.cpr
= readb(dd
->spp_cpr
);
227 parport_ax88796_restore_state(struct parport
*p
, struct parport_state
*s
)
229 struct ax_drvdata
*dd
= pp_to_drv(p
);
231 dev_dbg(dd
->dev
, "restore_state: %p: state=%p\n", p
, s
);
232 writeb(s
->u
.ax88796
.cpr
, dd
->spp_cpr
);
236 parport_ax88796_interrupt(int irq
, void *dev_id
)
238 parport_generic_irq(irq
, dev_id
);
243 static struct parport_operations parport_ax88796_ops
= {
244 .write_data
= parport_ax88796_write_data
,
245 .read_data
= parport_ax88796_read_data
,
247 .write_control
= parport_ax88796_write_control
,
248 .read_control
= parport_ax88796_read_control
,
249 .frob_control
= parport_ax88796_frob_control
,
251 .read_status
= parport_ax88796_read_status
,
253 .enable_irq
= parport_ax88796_enable_irq
,
254 .disable_irq
= parport_ax88796_disable_irq
,
256 .data_forward
= parport_ax88796_data_forward
,
257 .data_reverse
= parport_ax88796_data_reverse
,
259 .init_state
= parport_ax88796_init_state
,
260 .save_state
= parport_ax88796_save_state
,
261 .restore_state
= parport_ax88796_restore_state
,
263 .epp_write_data
= parport_ieee1284_epp_write_data
,
264 .epp_read_data
= parport_ieee1284_epp_read_data
,
265 .epp_write_addr
= parport_ieee1284_epp_write_addr
,
266 .epp_read_addr
= parport_ieee1284_epp_read_addr
,
268 .ecp_write_data
= parport_ieee1284_ecp_write_data
,
269 .ecp_read_data
= parport_ieee1284_ecp_read_data
,
270 .ecp_write_addr
= parport_ieee1284_ecp_write_addr
,
272 .compat_write_data
= parport_ieee1284_write_compat
,
273 .nibble_read_data
= parport_ieee1284_read_nibble
,
274 .byte_read_data
= parport_ieee1284_read_byte
,
276 .owner
= THIS_MODULE
,
279 static int parport_ax88796_probe(struct platform_device
*pdev
)
281 struct device
*_dev
= &pdev
->dev
;
282 struct ax_drvdata
*dd
;
283 struct parport
*pp
= NULL
;
284 struct resource
*res
;
290 dd
= kzalloc(sizeof(struct ax_drvdata
), GFP_KERNEL
);
292 dev_err(_dev
, "no memory for private data\n");
296 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
298 dev_err(_dev
, "no MEM specified\n");
303 size
= (res
->end
- res
->start
) + 1;
306 dd
->io
= request_mem_region(res
->start
, size
, pdev
->name
);
307 if (dd
->io
== NULL
) {
308 dev_err(_dev
, "cannot reserve memory\n");
313 dd
->base
= ioremap(res
->start
, size
);
314 if (dd
->base
== NULL
) {
315 dev_err(_dev
, "cannot ioremap region\n");
320 irq
= platform_get_irq(pdev
, 0);
322 irq
= PARPORT_IRQ_NONE
;
324 pp
= parport_register_port((unsigned long)dd
->base
, irq
,
326 &parport_ax88796_ops
);
329 dev_err(_dev
, "failed to register parallel port\n");
334 pp
->private_data
= dd
;
338 dd
->spp_data
= dd
->base
;
339 dd
->spp_spr
= dd
->base
+ (spacing
* 1);
340 dd
->spp_cpr
= dd
->base
+ (spacing
* 2);
342 /* initialise the port controls */
343 writeb(AX_CPR_STRB
, dd
->spp_cpr
);
347 ret
= request_irq(irq
, parport_ax88796_interrupt
,
348 IRQF_TRIGGER_FALLING
, pdev
->name
, pp
);
356 platform_set_drvdata(pdev
, pp
);
358 dev_info(_dev
, "attached parallel port driver\n");
359 parport_announce_port(pp
);
364 parport_remove_port(pp
);
368 release_resource(dd
->io
);
375 static int parport_ax88796_remove(struct platform_device
*pdev
)
377 struct parport
*p
= platform_get_drvdata(pdev
);
378 struct ax_drvdata
*dd
= pp_to_drv(p
);
381 parport_remove_port(p
);
383 release_resource(dd
->io
);
392 static int parport_ax88796_suspend(struct platform_device
*dev
,
395 struct parport
*p
= platform_get_drvdata(dev
);
396 struct ax_drvdata
*dd
= pp_to_drv(p
);
398 parport_ax88796_save_state(p
, &dd
->suspend
);
399 writeb(AX_CPR_nDOE
| AX_CPR_STRB
, dd
->spp_cpr
);
403 static int parport_ax88796_resume(struct platform_device
*dev
)
405 struct parport
*p
= platform_get_drvdata(dev
);
406 struct ax_drvdata
*dd
= pp_to_drv(p
);
408 parport_ax88796_restore_state(p
, &dd
->suspend
);
413 #define parport_ax88796_suspend NULL
414 #define parport_ax88796_resume NULL
417 static struct platform_driver axdrv
= {
419 .name
= "ax88796-pp",
420 .owner
= THIS_MODULE
,
422 .probe
= parport_ax88796_probe
,
423 .remove
= parport_ax88796_remove
,
424 .suspend
= parport_ax88796_suspend
,
425 .resume
= parport_ax88796_resume
,
428 static int __init
parport_ax88796_init(void)
430 return platform_driver_register(&axdrv
);
433 static void __exit
parport_ax88796_exit(void)
435 platform_driver_unregister(&axdrv
);
438 module_init(parport_ax88796_init
)
439 module_exit(parport_ax88796_exit
)
441 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
442 MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
443 MODULE_LICENSE("GPL");