2 * drivers/ata/pata_palmld.c
4 * Driver for IDE channel in Palm LifeDrive
6 * Based on research of:
7 * Alex Osborne <ato@meshy.org>
9 * Rewrite for mainline:
10 * Marek Vasut <marek.vasut@gmail.com>
12 * Rewritten version based on pata_ixp4xx_cf.c:
13 * ixp4xx PATA/Compact Flash driver
14 * Copyright (C) 2006-07 Tower Technologies
15 * Author: Alessandro Zummo <a.zummo@towertech.it>
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/libata.h>
26 #include <linux/irq.h>
27 #include <linux/platform_device.h>
28 #include <linux/delay.h>
29 #include <linux/gpio/consumer.h>
31 #include <scsi/scsi_host.h>
32 #include <mach/palmld.h>
34 #define DRV_NAME "pata_palmld"
37 struct ata_host
*host
;
38 struct gpio_desc
*power
;
39 struct gpio_desc
*reset
;
42 static struct scsi_host_template palmld_sht
= {
43 ATA_PIO_SHT(DRV_NAME
),
46 static struct ata_port_operations palmld_port_ops
= {
47 .inherits
= &ata_sff_port_ops
,
48 .sff_data_xfer
= ata_sff_data_xfer32
,
49 .cable_detect
= ata_cable_40wire
,
52 static int palmld_pata_probe(struct platform_device
*pdev
)
54 struct palmld_pata
*lda
;
57 struct device
*dev
= &pdev
->dev
;
60 lda
= devm_kzalloc(dev
, sizeof(*lda
), GFP_KERNEL
);
65 lda
->host
= ata_host_alloc(dev
, 1);
69 /* remap drive's physical memory address */
70 mem
= devm_ioremap(dev
, PALMLD_IDE_PHYS
, 0x1000);
74 /* request and activate power and reset GPIOs */
75 lda
->power
= devm_gpiod_get(dev
, "power", GPIOD_OUT_HIGH
);
76 if (IS_ERR(lda
->power
))
77 return PTR_ERR(lda
->power
);
78 lda
->reset
= devm_gpiod_get(dev
, "reset", GPIOD_OUT_HIGH
);
79 if (IS_ERR(lda
->reset
)) {
80 gpiod_set_value(lda
->power
, 0);
81 return PTR_ERR(lda
->reset
);
84 /* Assert reset to reset the drive */
85 gpiod_set_value(lda
->reset
, 1);
87 gpiod_set_value(lda
->reset
, 0);
90 /* setup the ata port */
91 ap
= lda
->host
->ports
[0];
92 ap
->ops
= &palmld_port_ops
;
93 ap
->pio_mask
= ATA_PIO4
;
94 ap
->flags
|= ATA_FLAG_PIO_POLLING
;
96 /* memory mapping voodoo */
97 ap
->ioaddr
.cmd_addr
= mem
+ 0x10;
98 ap
->ioaddr
.altstatus_addr
= mem
+ 0xe;
99 ap
->ioaddr
.ctl_addr
= mem
+ 0xe;
102 ata_sff_std_ports(&ap
->ioaddr
);
105 ret
= ata_host_activate(lda
->host
, 0, NULL
, IRQF_TRIGGER_RISING
,
107 /* power down on failure */
109 gpiod_set_value(lda
->power
, 0);
113 platform_set_drvdata(pdev
, lda
);
117 static int palmld_pata_remove(struct platform_device
*pdev
)
119 struct palmld_pata
*lda
= platform_get_drvdata(pdev
);
121 ata_platform_remove_one(pdev
);
123 /* power down the HDD */
124 gpiod_set_value(lda
->power
, 0);
129 static struct platform_driver palmld_pata_platform_driver
= {
133 .probe
= palmld_pata_probe
,
134 .remove
= palmld_pata_remove
,
137 module_platform_driver(palmld_pata_platform_driver
);
139 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
140 MODULE_DESCRIPTION("PalmLD PATA driver");
141 MODULE_LICENSE("GPL");
142 MODULE_ALIAS("platform:" DRV_NAME
);