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
);
235 static struct parport_operations parport_ax88796_ops
= {
236 .write_data
= parport_ax88796_write_data
,
237 .read_data
= parport_ax88796_read_data
,
239 .write_control
= parport_ax88796_write_control
,
240 .read_control
= parport_ax88796_read_control
,
241 .frob_control
= parport_ax88796_frob_control
,
243 .read_status
= parport_ax88796_read_status
,
245 .enable_irq
= parport_ax88796_enable_irq
,
246 .disable_irq
= parport_ax88796_disable_irq
,
248 .data_forward
= parport_ax88796_data_forward
,
249 .data_reverse
= parport_ax88796_data_reverse
,
251 .init_state
= parport_ax88796_init_state
,
252 .save_state
= parport_ax88796_save_state
,
253 .restore_state
= parport_ax88796_restore_state
,
255 .epp_write_data
= parport_ieee1284_epp_write_data
,
256 .epp_read_data
= parport_ieee1284_epp_read_data
,
257 .epp_write_addr
= parport_ieee1284_epp_write_addr
,
258 .epp_read_addr
= parport_ieee1284_epp_read_addr
,
260 .ecp_write_data
= parport_ieee1284_ecp_write_data
,
261 .ecp_read_data
= parport_ieee1284_ecp_read_data
,
262 .ecp_write_addr
= parport_ieee1284_ecp_write_addr
,
264 .compat_write_data
= parport_ieee1284_write_compat
,
265 .nibble_read_data
= parport_ieee1284_read_nibble
,
266 .byte_read_data
= parport_ieee1284_read_byte
,
268 .owner
= THIS_MODULE
,
271 static int parport_ax88796_probe(struct platform_device
*pdev
)
273 struct device
*_dev
= &pdev
->dev
;
274 struct ax_drvdata
*dd
;
275 struct parport
*pp
= NULL
;
276 struct resource
*res
;
282 dd
= kzalloc(sizeof(struct ax_drvdata
), GFP_KERNEL
);
284 dev_err(_dev
, "no memory for private data\n");
288 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
290 dev_err(_dev
, "no MEM specified\n");
295 size
= (res
->end
- res
->start
) + 1;
298 dd
->io
= request_mem_region(res
->start
, size
, pdev
->name
);
299 if (dd
->io
== NULL
) {
300 dev_err(_dev
, "cannot reserve memory\n");
305 dd
->base
= ioremap(res
->start
, size
);
306 if (dd
->base
== NULL
) {
307 dev_err(_dev
, "cannot ioremap region\n");
312 irq
= platform_get_irq(pdev
, 0);
314 irq
= PARPORT_IRQ_NONE
;
316 pp
= parport_register_port((unsigned long)dd
->base
, irq
,
318 &parport_ax88796_ops
);
321 dev_err(_dev
, "failed to register parallel port\n");
326 pp
->private_data
= dd
;
330 dd
->spp_data
= dd
->base
;
331 dd
->spp_spr
= dd
->base
+ (spacing
* 1);
332 dd
->spp_cpr
= dd
->base
+ (spacing
* 2);
334 /* initialise the port controls */
335 writeb(AX_CPR_STRB
, dd
->spp_cpr
);
339 ret
= request_irq(irq
, parport_irq_handler
,
340 IRQF_TRIGGER_FALLING
, pdev
->name
, pp
);
348 platform_set_drvdata(pdev
, pp
);
350 dev_info(_dev
, "attached parallel port driver\n");
351 parport_announce_port(pp
);
356 parport_remove_port(pp
);
360 release_resource(dd
->io
);
367 static int parport_ax88796_remove(struct platform_device
*pdev
)
369 struct parport
*p
= platform_get_drvdata(pdev
);
370 struct ax_drvdata
*dd
= pp_to_drv(p
);
373 parport_remove_port(p
);
375 release_resource(dd
->io
);
384 static int parport_ax88796_suspend(struct platform_device
*dev
,
387 struct parport
*p
= platform_get_drvdata(dev
);
388 struct ax_drvdata
*dd
= pp_to_drv(p
);
390 parport_ax88796_save_state(p
, &dd
->suspend
);
391 writeb(AX_CPR_nDOE
| AX_CPR_STRB
, dd
->spp_cpr
);
395 static int parport_ax88796_resume(struct platform_device
*dev
)
397 struct parport
*p
= platform_get_drvdata(dev
);
398 struct ax_drvdata
*dd
= pp_to_drv(p
);
400 parport_ax88796_restore_state(p
, &dd
->suspend
);
405 #define parport_ax88796_suspend NULL
406 #define parport_ax88796_resume NULL
409 MODULE_ALIAS("platform:ax88796-pp");
411 static struct platform_driver axdrv
= {
413 .name
= "ax88796-pp",
414 .owner
= THIS_MODULE
,
416 .probe
= parport_ax88796_probe
,
417 .remove
= parport_ax88796_remove
,
418 .suspend
= parport_ax88796_suspend
,
419 .resume
= parport_ax88796_resume
,
422 static int __init
parport_ax88796_init(void)
424 return platform_driver_register(&axdrv
);
427 static void __exit
parport_ax88796_exit(void)
429 platform_driver_unregister(&axdrv
);
432 module_init(parport_ax88796_init
)
433 module_exit(parport_ax88796_exit
)
435 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
436 MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
437 MODULE_LICENSE("GPL");