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
;
277 struct resource
*res
;
283 dd
= kzalloc(sizeof(*dd
), GFP_KERNEL
);
287 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
289 dev_err(_dev
, "no MEM specified\n");
294 size
= resource_size(res
);
297 dd
->io
= request_mem_region(res
->start
, size
, pdev
->name
);
298 if (dd
->io
== NULL
) {
299 dev_err(_dev
, "cannot reserve memory\n");
304 dd
->base
= ioremap(res
->start
, size
);
305 if (dd
->base
== NULL
) {
306 dev_err(_dev
, "cannot ioremap region\n");
311 irq
= platform_get_irq(pdev
, 0);
313 irq
= PARPORT_IRQ_NONE
;
315 pp
= parport_register_port((unsigned long)dd
->base
, irq
,
317 &parport_ax88796_ops
);
320 dev_err(_dev
, "failed to register parallel port\n");
325 pp
->private_data
= dd
;
329 dd
->spp_data
= dd
->base
;
330 dd
->spp_spr
= dd
->base
+ (spacing
* 1);
331 dd
->spp_cpr
= dd
->base
+ (spacing
* 2);
333 /* initialise the port controls */
334 writeb(AX_CPR_STRB
, dd
->spp_cpr
);
338 ret
= request_irq(irq
, parport_irq_handler
,
339 IRQF_TRIGGER_FALLING
, pdev
->name
, pp
);
347 platform_set_drvdata(pdev
, pp
);
349 dev_info(_dev
, "attached parallel port driver\n");
350 parport_announce_port(pp
);
355 parport_remove_port(pp
);
359 release_mem_region(dd
->io
->start
, size
);
365 static int parport_ax88796_remove(struct platform_device
*pdev
)
367 struct parport
*p
= platform_get_drvdata(pdev
);
368 struct ax_drvdata
*dd
= pp_to_drv(p
);
371 parport_remove_port(p
);
373 release_mem_region(dd
->io
->start
, resource_size(dd
->io
));
381 static int parport_ax88796_suspend(struct platform_device
*dev
,
384 struct parport
*p
= platform_get_drvdata(dev
);
385 struct ax_drvdata
*dd
= pp_to_drv(p
);
387 parport_ax88796_save_state(p
, &dd
->suspend
);
388 writeb(AX_CPR_nDOE
| AX_CPR_STRB
, dd
->spp_cpr
);
392 static int parport_ax88796_resume(struct platform_device
*dev
)
394 struct parport
*p
= platform_get_drvdata(dev
);
395 struct ax_drvdata
*dd
= pp_to_drv(p
);
397 parport_ax88796_restore_state(p
, &dd
->suspend
);
402 #define parport_ax88796_suspend NULL
403 #define parport_ax88796_resume NULL
406 MODULE_ALIAS("platform:ax88796-pp");
408 static struct platform_driver axdrv
= {
410 .name
= "ax88796-pp",
412 .probe
= parport_ax88796_probe
,
413 .remove
= parport_ax88796_remove
,
414 .suspend
= parport_ax88796_suspend
,
415 .resume
= parport_ax88796_resume
,
418 module_platform_driver(axdrv
);
420 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
421 MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
422 MODULE_LICENSE("GPL");