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>
18 #include <linux/slab.h>
23 #define AX_SPR_BUSY (1<<7)
24 #define AX_SPR_ACK (1<<6)
25 #define AX_SPR_PE (1<<5)
26 #define AX_SPR_SLCT (1<<4)
27 #define AX_SPR_ERR (1<<3)
29 #define AX_CPR_nDOE (1<<5)
30 #define AX_CPR_SLCTIN (1<<3)
31 #define AX_CPR_nINIT (1<<2)
32 #define AX_CPR_ATFD (1<<1)
33 #define AX_CPR_STRB (1<<0)
36 struct parport
*parport
;
37 struct parport_state suspend
;
42 unsigned char irq_enabled
;
45 void __iomem
*spp_data
;
46 void __iomem
*spp_spr
;
47 void __iomem
*spp_cpr
;
50 static inline struct ax_drvdata
*pp_to_drv(struct parport
*p
)
52 return p
->private_data
;
56 parport_ax88796_read_data(struct parport
*p
)
58 struct ax_drvdata
*dd
= pp_to_drv(p
);
60 return readb(dd
->spp_data
);
64 parport_ax88796_write_data(struct parport
*p
, unsigned char data
)
66 struct ax_drvdata
*dd
= pp_to_drv(p
);
68 writeb(data
, dd
->spp_data
);
72 parport_ax88796_read_control(struct parport
*p
)
74 struct ax_drvdata
*dd
= pp_to_drv(p
);
75 unsigned int cpr
= readb(dd
->spp_cpr
);
78 if (!(cpr
& AX_CPR_STRB
))
79 ret
|= PARPORT_CONTROL_STROBE
;
81 if (!(cpr
& AX_CPR_ATFD
))
82 ret
|= PARPORT_CONTROL_AUTOFD
;
84 if (cpr
& AX_CPR_nINIT
)
85 ret
|= PARPORT_CONTROL_INIT
;
87 if (!(cpr
& AX_CPR_SLCTIN
))
88 ret
|= PARPORT_CONTROL_SELECT
;
94 parport_ax88796_write_control(struct parport
*p
, unsigned char control
)
96 struct ax_drvdata
*dd
= pp_to_drv(p
);
97 unsigned int cpr
= readb(dd
->spp_cpr
);
101 if (!(control
& PARPORT_CONTROL_STROBE
))
104 if (!(control
& PARPORT_CONTROL_AUTOFD
))
107 if (control
& PARPORT_CONTROL_INIT
)
110 if (!(control
& PARPORT_CONTROL_SELECT
))
111 cpr
|= AX_CPR_SLCTIN
;
113 dev_dbg(dd
->dev
, "write_control: ctrl=%02x, cpr=%02x\n", control
, cpr
);
114 writeb(cpr
, dd
->spp_cpr
);
116 if (parport_ax88796_read_control(p
) != control
) {
117 dev_err(dd
->dev
, "write_control: read != set (%02x, %02x)\n",
118 parport_ax88796_read_control(p
), control
);
123 parport_ax88796_read_status(struct parport
*p
)
125 struct ax_drvdata
*dd
= pp_to_drv(p
);
126 unsigned int status
= readb(dd
->spp_spr
);
127 unsigned int ret
= 0;
129 if (status
& AX_SPR_BUSY
)
130 ret
|= PARPORT_STATUS_BUSY
;
132 if (status
& AX_SPR_ACK
)
133 ret
|= PARPORT_STATUS_ACK
;
135 if (status
& AX_SPR_ERR
)
136 ret
|= PARPORT_STATUS_ERROR
;
138 if (status
& AX_SPR_SLCT
)
139 ret
|= PARPORT_STATUS_SELECT
;
141 if (status
& AX_SPR_PE
)
142 ret
|= PARPORT_STATUS_PAPEROUT
;
148 parport_ax88796_frob_control(struct parport
*p
, unsigned char mask
,
151 struct ax_drvdata
*dd
= pp_to_drv(p
);
152 unsigned char old
= parport_ax88796_read_control(p
);
154 dev_dbg(dd
->dev
, "frob: mask=%02x, val=%02x, old=%02x\n",
157 parport_ax88796_write_control(p
, (old
& ~mask
) | val
);
162 parport_ax88796_enable_irq(struct parport
*p
)
164 struct ax_drvdata
*dd
= pp_to_drv(p
);
167 local_irq_save(flags
);
168 if (!dd
->irq_enabled
) {
172 local_irq_restore(flags
);
176 parport_ax88796_disable_irq(struct parport
*p
)
178 struct ax_drvdata
*dd
= pp_to_drv(p
);
181 local_irq_save(flags
);
182 if (dd
->irq_enabled
) {
186 local_irq_restore(flags
);
190 parport_ax88796_data_forward(struct parport
*p
)
192 struct ax_drvdata
*dd
= pp_to_drv(p
);
193 void __iomem
*cpr
= dd
->spp_cpr
;
195 writeb((readb(cpr
) & ~AX_CPR_nDOE
), cpr
);
199 parport_ax88796_data_reverse(struct parport
*p
)
201 struct ax_drvdata
*dd
= pp_to_drv(p
);
202 void __iomem
*cpr
= dd
->spp_cpr
;
204 writeb(readb(cpr
) | AX_CPR_nDOE
, cpr
);
208 parport_ax88796_init_state(struct pardevice
*d
, struct parport_state
*s
)
210 struct ax_drvdata
*dd
= pp_to_drv(d
->port
);
212 memset(s
, 0, sizeof(struct parport_state
));
214 dev_dbg(dd
->dev
, "init_state: %p: state=%p\n", d
, s
);
215 s
->u
.ax88796
.cpr
= readb(dd
->spp_cpr
);
219 parport_ax88796_save_state(struct parport
*p
, struct parport_state
*s
)
221 struct ax_drvdata
*dd
= pp_to_drv(p
);
223 dev_dbg(dd
->dev
, "save_state: %p: state=%p\n", p
, s
);
224 s
->u
.ax88796
.cpr
= readb(dd
->spp_cpr
);
228 parport_ax88796_restore_state(struct parport
*p
, struct parport_state
*s
)
230 struct ax_drvdata
*dd
= pp_to_drv(p
);
232 dev_dbg(dd
->dev
, "restore_state: %p: state=%p\n", p
, s
);
233 writeb(s
->u
.ax88796
.cpr
, dd
->spp_cpr
);
236 static struct parport_operations parport_ax88796_ops
= {
237 .write_data
= parport_ax88796_write_data
,
238 .read_data
= parport_ax88796_read_data
,
240 .write_control
= parport_ax88796_write_control
,
241 .read_control
= parport_ax88796_read_control
,
242 .frob_control
= parport_ax88796_frob_control
,
244 .read_status
= parport_ax88796_read_status
,
246 .enable_irq
= parport_ax88796_enable_irq
,
247 .disable_irq
= parport_ax88796_disable_irq
,
249 .data_forward
= parport_ax88796_data_forward
,
250 .data_reverse
= parport_ax88796_data_reverse
,
252 .init_state
= parport_ax88796_init_state
,
253 .save_state
= parport_ax88796_save_state
,
254 .restore_state
= parport_ax88796_restore_state
,
256 .epp_write_data
= parport_ieee1284_epp_write_data
,
257 .epp_read_data
= parport_ieee1284_epp_read_data
,
258 .epp_write_addr
= parport_ieee1284_epp_write_addr
,
259 .epp_read_addr
= parport_ieee1284_epp_read_addr
,
261 .ecp_write_data
= parport_ieee1284_ecp_write_data
,
262 .ecp_read_data
= parport_ieee1284_ecp_read_data
,
263 .ecp_write_addr
= parport_ieee1284_ecp_write_addr
,
265 .compat_write_data
= parport_ieee1284_write_compat
,
266 .nibble_read_data
= parport_ieee1284_read_nibble
,
267 .byte_read_data
= parport_ieee1284_read_byte
,
269 .owner
= THIS_MODULE
,
272 static int parport_ax88796_probe(struct platform_device
*pdev
)
274 struct device
*_dev
= &pdev
->dev
;
275 struct ax_drvdata
*dd
;
276 struct parport
*pp
= NULL
;
277 struct resource
*res
;
283 dd
= kzalloc(sizeof(struct ax_drvdata
), GFP_KERNEL
);
285 dev_err(_dev
, "no memory for private data\n");
289 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
291 dev_err(_dev
, "no MEM specified\n");
296 size
= (res
->end
- res
->start
) + 1;
299 dd
->io
= request_mem_region(res
->start
, size
, pdev
->name
);
300 if (dd
->io
== NULL
) {
301 dev_err(_dev
, "cannot reserve memory\n");
306 dd
->base
= ioremap(res
->start
, size
);
307 if (dd
->base
== NULL
) {
308 dev_err(_dev
, "cannot ioremap region\n");
313 irq
= platform_get_irq(pdev
, 0);
315 irq
= PARPORT_IRQ_NONE
;
317 pp
= parport_register_port((unsigned long)dd
->base
, irq
,
319 &parport_ax88796_ops
);
322 dev_err(_dev
, "failed to register parallel port\n");
327 pp
->private_data
= dd
;
331 dd
->spp_data
= dd
->base
;
332 dd
->spp_spr
= dd
->base
+ (spacing
* 1);
333 dd
->spp_cpr
= dd
->base
+ (spacing
* 2);
335 /* initialise the port controls */
336 writeb(AX_CPR_STRB
, dd
->spp_cpr
);
340 ret
= request_irq(irq
, parport_irq_handler
,
341 IRQF_TRIGGER_FALLING
, pdev
->name
, pp
);
349 platform_set_drvdata(pdev
, pp
);
351 dev_info(_dev
, "attached parallel port driver\n");
352 parport_announce_port(pp
);
357 parport_remove_port(pp
);
361 release_resource(dd
->io
);
368 static int parport_ax88796_remove(struct platform_device
*pdev
)
370 struct parport
*p
= platform_get_drvdata(pdev
);
371 struct ax_drvdata
*dd
= pp_to_drv(p
);
374 parport_remove_port(p
);
376 release_resource(dd
->io
);
385 static int parport_ax88796_suspend(struct platform_device
*dev
,
388 struct parport
*p
= platform_get_drvdata(dev
);
389 struct ax_drvdata
*dd
= pp_to_drv(p
);
391 parport_ax88796_save_state(p
, &dd
->suspend
);
392 writeb(AX_CPR_nDOE
| AX_CPR_STRB
, dd
->spp_cpr
);
396 static int parport_ax88796_resume(struct platform_device
*dev
)
398 struct parport
*p
= platform_get_drvdata(dev
);
399 struct ax_drvdata
*dd
= pp_to_drv(p
);
401 parport_ax88796_restore_state(p
, &dd
->suspend
);
406 #define parport_ax88796_suspend NULL
407 #define parport_ax88796_resume NULL
410 MODULE_ALIAS("platform:ax88796-pp");
412 static struct platform_driver axdrv
= {
414 .name
= "ax88796-pp",
415 .owner
= THIS_MODULE
,
417 .probe
= parport_ax88796_probe
,
418 .remove
= parport_ax88796_remove
,
419 .suspend
= parport_ax88796_suspend
,
420 .resume
= parport_ax88796_resume
,
423 static int __init
parport_ax88796_init(void)
425 return platform_driver_register(&axdrv
);
428 static void __exit
parport_ax88796_exit(void)
430 platform_driver_unregister(&axdrv
);
433 module_init(parport_ax88796_init
)
434 module_exit(parport_ax88796_exit
)
436 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
437 MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
438 MODULE_LICENSE("GPL");