root/drivers/parport/parport_ax88796.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pp_to_drv
  2. parport_ax88796_read_data
  3. parport_ax88796_write_data
  4. parport_ax88796_read_control
  5. parport_ax88796_write_control
  6. parport_ax88796_read_status
  7. parport_ax88796_frob_control
  8. parport_ax88796_enable_irq
  9. parport_ax88796_disable_irq
  10. parport_ax88796_data_forward
  11. parport_ax88796_data_reverse
  12. parport_ax88796_init_state
  13. parport_ax88796_save_state
  14. parport_ax88796_restore_state
  15. parport_ax88796_probe
  16. parport_ax88796_remove
  17. parport_ax88796_suspend
  18. parport_ax88796_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* linux/drivers/parport/parport_ax88796.c
   3  *
   4  * (c) 2005,2006 Simtec Electronics
   5  *      Ben Dooks <ben@simtec.co.uk>
   6 */
   7 
   8 #include <linux/module.h>
   9 #include <linux/kernel.h>
  10 #include <linux/parport.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/errno.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/slab.h>
  15 
  16 #include <asm/io.h>
  17 #include <asm/irq.h>
  18 
  19 #define AX_SPR_BUSY             (1<<7)
  20 #define AX_SPR_ACK              (1<<6)
  21 #define AX_SPR_PE               (1<<5)
  22 #define AX_SPR_SLCT             (1<<4)
  23 #define AX_SPR_ERR              (1<<3)
  24 
  25 #define AX_CPR_nDOE             (1<<5)
  26 #define AX_CPR_SLCTIN           (1<<3)
  27 #define AX_CPR_nINIT            (1<<2)
  28 #define AX_CPR_ATFD             (1<<1)
  29 #define AX_CPR_STRB             (1<<0)
  30 
  31 struct ax_drvdata {
  32         struct parport          *parport;
  33         struct parport_state     suspend;
  34 
  35         struct device           *dev;
  36         struct resource         *io;
  37 
  38         unsigned char            irq_enabled;
  39 
  40         void __iomem            *base;
  41         void __iomem            *spp_data;
  42         void __iomem            *spp_spr;
  43         void __iomem            *spp_cpr;
  44 };
  45 
  46 static inline struct ax_drvdata *pp_to_drv(struct parport *p)
  47 {
  48         return p->private_data;
  49 }
  50 
  51 static unsigned char
  52 parport_ax88796_read_data(struct parport *p)
  53 {
  54         struct ax_drvdata *dd = pp_to_drv(p);
  55 
  56         return readb(dd->spp_data);
  57 }
  58 
  59 static void
  60 parport_ax88796_write_data(struct parport *p, unsigned char data)
  61 {
  62         struct ax_drvdata *dd = pp_to_drv(p);
  63 
  64         writeb(data, dd->spp_data);
  65 }
  66 
  67 static unsigned char
  68 parport_ax88796_read_control(struct parport *p)
  69 {
  70         struct ax_drvdata *dd = pp_to_drv(p);
  71         unsigned int cpr = readb(dd->spp_cpr);
  72         unsigned int ret = 0;
  73 
  74         if (!(cpr & AX_CPR_STRB))
  75                 ret |= PARPORT_CONTROL_STROBE;
  76 
  77         if (!(cpr & AX_CPR_ATFD))
  78                 ret |= PARPORT_CONTROL_AUTOFD;
  79 
  80         if (cpr & AX_CPR_nINIT)
  81                 ret |= PARPORT_CONTROL_INIT;
  82 
  83         if (!(cpr & AX_CPR_SLCTIN))
  84                 ret |= PARPORT_CONTROL_SELECT;
  85 
  86         return ret;
  87 }
  88 
  89 static void
  90 parport_ax88796_write_control(struct parport *p, unsigned char control)
  91 {
  92         struct ax_drvdata *dd = pp_to_drv(p);
  93         unsigned int cpr = readb(dd->spp_cpr);
  94 
  95         cpr &= AX_CPR_nDOE;
  96 
  97         if (!(control & PARPORT_CONTROL_STROBE))
  98                 cpr |= AX_CPR_STRB;
  99 
 100         if (!(control & PARPORT_CONTROL_AUTOFD))
 101                 cpr |= AX_CPR_ATFD;
 102 
 103         if (control & PARPORT_CONTROL_INIT)
 104                 cpr |= AX_CPR_nINIT;
 105 
 106         if (!(control & PARPORT_CONTROL_SELECT))
 107                 cpr |= AX_CPR_SLCTIN;
 108 
 109         dev_dbg(dd->dev, "write_control: ctrl=%02x, cpr=%02x\n", control, cpr);
 110         writeb(cpr, dd->spp_cpr);
 111 
 112         if (parport_ax88796_read_control(p) != control) {
 113                 dev_err(dd->dev, "write_control: read != set (%02x, %02x)\n",
 114                         parport_ax88796_read_control(p), control);
 115         }
 116 }
 117 
 118 static unsigned char
 119 parport_ax88796_read_status(struct parport *p)
 120 {
 121         struct ax_drvdata *dd = pp_to_drv(p);
 122         unsigned int status = readb(dd->spp_spr);
 123         unsigned int ret = 0;
 124 
 125         if (status & AX_SPR_BUSY)
 126                 ret |= PARPORT_STATUS_BUSY;
 127 
 128         if (status & AX_SPR_ACK)
 129                 ret |= PARPORT_STATUS_ACK;
 130 
 131         if (status & AX_SPR_ERR)
 132                 ret |= PARPORT_STATUS_ERROR;
 133 
 134         if (status & AX_SPR_SLCT)
 135                 ret |= PARPORT_STATUS_SELECT;
 136 
 137         if (status & AX_SPR_PE)
 138                 ret |= PARPORT_STATUS_PAPEROUT;
 139 
 140         return ret;
 141 }
 142 
 143 static unsigned char
 144 parport_ax88796_frob_control(struct parport *p, unsigned char mask,
 145                              unsigned char val)
 146 {
 147         struct ax_drvdata *dd = pp_to_drv(p);
 148         unsigned char old = parport_ax88796_read_control(p);
 149 
 150         dev_dbg(dd->dev, "frob: mask=%02x, val=%02x, old=%02x\n",
 151                 mask, val, old);
 152 
 153         parport_ax88796_write_control(p, (old & ~mask) | val);
 154         return old;
 155 }
 156 
 157 static void
 158 parport_ax88796_enable_irq(struct parport *p)
 159 {
 160         struct ax_drvdata *dd = pp_to_drv(p);
 161         unsigned long flags;
 162 
 163         local_irq_save(flags);
 164         if (!dd->irq_enabled) {
 165                 enable_irq(p->irq);
 166                 dd->irq_enabled = 1;
 167         }
 168         local_irq_restore(flags);
 169 }
 170 
 171 static void
 172 parport_ax88796_disable_irq(struct parport *p)
 173 {
 174         struct ax_drvdata *dd = pp_to_drv(p);
 175         unsigned long flags;
 176 
 177         local_irq_save(flags);
 178         if (dd->irq_enabled) {
 179                 disable_irq(p->irq);
 180                 dd->irq_enabled = 0;
 181         }
 182         local_irq_restore(flags);
 183 }
 184 
 185 static void
 186 parport_ax88796_data_forward(struct parport *p)
 187 {
 188         struct ax_drvdata *dd = pp_to_drv(p);
 189         void __iomem *cpr = dd->spp_cpr;
 190 
 191         writeb((readb(cpr) & ~AX_CPR_nDOE), cpr);
 192 }
 193 
 194 static void
 195 parport_ax88796_data_reverse(struct parport *p)
 196 {
 197         struct ax_drvdata *dd = pp_to_drv(p);
 198         void __iomem *cpr = dd->spp_cpr;
 199 
 200         writeb(readb(cpr) | AX_CPR_nDOE, cpr);
 201 }
 202 
 203 static void
 204 parport_ax88796_init_state(struct pardevice *d, struct parport_state *s)
 205 {
 206         struct ax_drvdata *dd = pp_to_drv(d->port);
 207 
 208         memset(s, 0, sizeof(struct parport_state));
 209 
 210         dev_dbg(dd->dev, "init_state: %p: state=%p\n", d, s);
 211         s->u.ax88796.cpr = readb(dd->spp_cpr);
 212 }
 213 
 214 static void
 215 parport_ax88796_save_state(struct parport *p, struct parport_state *s)
 216 {
 217         struct ax_drvdata *dd = pp_to_drv(p);
 218 
 219         dev_dbg(dd->dev, "save_state: %p: state=%p\n", p, s);
 220         s->u.ax88796.cpr = readb(dd->spp_cpr);
 221 }
 222 
 223 static void
 224 parport_ax88796_restore_state(struct parport *p, struct parport_state *s)
 225 {
 226         struct ax_drvdata *dd = pp_to_drv(p);
 227 
 228         dev_dbg(dd->dev, "restore_state: %p: state=%p\n", p, s);
 229         writeb(s->u.ax88796.cpr, dd->spp_cpr);
 230 }
 231 
 232 static struct parport_operations parport_ax88796_ops = {
 233         .write_data     = parport_ax88796_write_data,
 234         .read_data      = parport_ax88796_read_data,
 235 
 236         .write_control  = parport_ax88796_write_control,
 237         .read_control   = parport_ax88796_read_control,
 238         .frob_control   = parport_ax88796_frob_control,
 239 
 240         .read_status    = parport_ax88796_read_status,
 241 
 242         .enable_irq     = parport_ax88796_enable_irq,
 243         .disable_irq    = parport_ax88796_disable_irq,
 244 
 245         .data_forward   = parport_ax88796_data_forward,
 246         .data_reverse   = parport_ax88796_data_reverse,
 247 
 248         .init_state     = parport_ax88796_init_state,
 249         .save_state     = parport_ax88796_save_state,
 250         .restore_state  = parport_ax88796_restore_state,
 251 
 252         .epp_write_data = parport_ieee1284_epp_write_data,
 253         .epp_read_data  = parport_ieee1284_epp_read_data,
 254         .epp_write_addr = parport_ieee1284_epp_write_addr,
 255         .epp_read_addr  = parport_ieee1284_epp_read_addr,
 256 
 257         .ecp_write_data = parport_ieee1284_ecp_write_data,
 258         .ecp_read_data  = parport_ieee1284_ecp_read_data,
 259         .ecp_write_addr = parport_ieee1284_ecp_write_addr,
 260 
 261         .compat_write_data      = parport_ieee1284_write_compat,
 262         .nibble_read_data       = parport_ieee1284_read_nibble,
 263         .byte_read_data         = parport_ieee1284_read_byte,
 264 
 265         .owner          = THIS_MODULE,
 266 };
 267 
 268 static int parport_ax88796_probe(struct platform_device *pdev)
 269 {
 270         struct device *_dev = &pdev->dev;
 271         struct ax_drvdata *dd;
 272         struct parport *pp;
 273         struct resource *res;
 274         unsigned long size;
 275         int spacing;
 276         int irq;
 277         int ret;
 278 
 279         dd = kzalloc(sizeof(*dd), GFP_KERNEL);
 280         if (!dd)
 281                 return -ENOMEM;
 282 
 283         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 284         if (res == NULL) {
 285                 dev_err(_dev, "no MEM specified\n");
 286                 ret = -ENXIO;
 287                 goto exit_mem;
 288         }
 289 
 290         size = resource_size(res);
 291         spacing = size / 3;
 292 
 293         dd->io = request_mem_region(res->start, size, pdev->name);
 294         if (dd->io == NULL) {
 295                 dev_err(_dev, "cannot reserve memory\n");
 296                 ret = -ENXIO;
 297                 goto exit_mem;
 298         }
 299 
 300         dd->base = ioremap(res->start, size);
 301         if (dd->base == NULL) {
 302                 dev_err(_dev, "cannot ioremap region\n");
 303                 ret = -ENXIO;
 304                 goto exit_res;
 305         }
 306 
 307         irq = platform_get_irq(pdev, 0);
 308         if (irq <= 0)
 309                 irq = PARPORT_IRQ_NONE;
 310 
 311         pp = parport_register_port((unsigned long)dd->base, irq,
 312                                    PARPORT_DMA_NONE,
 313                                    &parport_ax88796_ops);
 314 
 315         if (pp == NULL) {
 316                 dev_err(_dev, "failed to register parallel port\n");
 317                 ret = -ENOMEM;
 318                 goto exit_unmap;
 319         }
 320 
 321         pp->private_data = dd;
 322         dd->parport = pp;
 323         dd->dev = _dev;
 324 
 325         dd->spp_data = dd->base;
 326         dd->spp_spr  = dd->base + (spacing * 1);
 327         dd->spp_cpr  = dd->base + (spacing * 2);
 328 
 329         /* initialise the port controls */
 330         writeb(AX_CPR_STRB, dd->spp_cpr);
 331 
 332         if (irq >= 0) {
 333                 /* request irq */
 334                 ret = request_irq(irq, parport_irq_handler,
 335                                   IRQF_TRIGGER_FALLING, pdev->name, pp);
 336 
 337                 if (ret < 0)
 338                         goto exit_port;
 339 
 340                 dd->irq_enabled = 1;
 341         }
 342 
 343         platform_set_drvdata(pdev, pp);
 344 
 345         dev_info(_dev, "attached parallel port driver\n");
 346         parport_announce_port(pp);
 347 
 348         return 0;
 349 
 350  exit_port:
 351         parport_remove_port(pp);
 352  exit_unmap:
 353         iounmap(dd->base);
 354  exit_res:
 355         release_mem_region(dd->io->start, size);
 356  exit_mem:
 357         kfree(dd);
 358         return ret;
 359 }
 360 
 361 static int parport_ax88796_remove(struct platform_device *pdev)
 362 {
 363         struct parport *p = platform_get_drvdata(pdev);
 364         struct ax_drvdata *dd = pp_to_drv(p);
 365 
 366         free_irq(p->irq, p);
 367         parport_remove_port(p);
 368         iounmap(dd->base);
 369         release_mem_region(dd->io->start, resource_size(dd->io));
 370         kfree(dd);
 371 
 372         return 0;
 373 }
 374 
 375 #ifdef CONFIG_PM
 376 
 377 static int parport_ax88796_suspend(struct platform_device *dev,
 378                                    pm_message_t state)
 379 {
 380         struct parport *p = platform_get_drvdata(dev);
 381         struct ax_drvdata *dd = pp_to_drv(p);
 382 
 383         parport_ax88796_save_state(p, &dd->suspend);
 384         writeb(AX_CPR_nDOE | AX_CPR_STRB, dd->spp_cpr);
 385         return 0;
 386 }
 387 
 388 static int parport_ax88796_resume(struct platform_device *dev)
 389 {
 390         struct parport *p = platform_get_drvdata(dev);
 391         struct ax_drvdata *dd = pp_to_drv(p);
 392 
 393         parport_ax88796_restore_state(p, &dd->suspend);
 394         return 0;
 395 }
 396 
 397 #else
 398 #define parport_ax88796_suspend NULL
 399 #define parport_ax88796_resume  NULL
 400 #endif
 401 
 402 MODULE_ALIAS("platform:ax88796-pp");
 403 
 404 static struct platform_driver axdrv = {
 405         .driver         = {
 406                 .name   = "ax88796-pp",
 407         },
 408         .probe          = parport_ax88796_probe,
 409         .remove         = parport_ax88796_remove,
 410         .suspend        = parport_ax88796_suspend,
 411         .resume         = parport_ax88796_resume,
 412 };
 413 
 414 module_platform_driver(axdrv);
 415 
 416 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 417 MODULE_DESCRIPTION("AX88796 Parport parallel port driver");
 418 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */