linux/drivers/ata/pata_palmld.c
<<
>>
Prefs
   1/*
   2 * drivers/ata/pata_palmld.c
   3 *
   4 * Driver for IDE channel in Palm LifeDrive
   5 *
   6 * Based on research of:
   7 *              Alex Osborne <ato@meshy.org>
   8 *
   9 * Rewrite for mainline:
  10 *              Marek Vasut <marek.vasut@gmail.com>
  11 *
  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>
  16 *
  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.
  20 *
  21 */
  22
  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.h>
  30
  31#include <scsi/scsi_host.h>
  32#include <mach/palmld.h>
  33
  34#define DRV_NAME "pata_palmld"
  35
  36static struct gpio palmld_hdd_gpios[] = {
  37        { GPIO_NR_PALMLD_IDE_PWEN,      GPIOF_INIT_HIGH,        "HDD Power" },
  38        { GPIO_NR_PALMLD_IDE_RESET,     GPIOF_INIT_LOW,         "HDD Reset" },
  39};
  40
  41static struct scsi_host_template palmld_sht = {
  42        ATA_PIO_SHT(DRV_NAME),
  43};
  44
  45static struct ata_port_operations palmld_port_ops = {
  46        .inherits               = &ata_sff_port_ops,
  47        .sff_data_xfer          = ata_sff_data_xfer_noirq,
  48        .cable_detect           = ata_cable_40wire,
  49};
  50
  51static int palmld_pata_probe(struct platform_device *pdev)
  52{
  53        struct ata_host *host;
  54        struct ata_port *ap;
  55        void __iomem *mem;
  56        int ret;
  57
  58        /* allocate host */
  59        host = ata_host_alloc(&pdev->dev, 1);
  60        if (!host) {
  61                ret = -ENOMEM;
  62                goto err1;
  63        }
  64
  65        /* remap drive's physical memory address */
  66        mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000);
  67        if (!mem) {
  68                ret = -ENOMEM;
  69                goto err1;
  70        }
  71
  72        /* request and activate power GPIO, IRQ GPIO */
  73        ret = gpio_request_array(palmld_hdd_gpios,
  74                                ARRAY_SIZE(palmld_hdd_gpios));
  75        if (ret)
  76                goto err1;
  77
  78        /* reset the drive */
  79        gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0);
  80        msleep(30);
  81        gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 1);
  82        msleep(30);
  83
  84        /* setup the ata port */
  85        ap = host->ports[0];
  86        ap->ops = &palmld_port_ops;
  87        ap->pio_mask = ATA_PIO4;
  88        ap->flags |= ATA_FLAG_PIO_POLLING;
  89
  90        /* memory mapping voodoo */
  91        ap->ioaddr.cmd_addr = mem + 0x10;
  92        ap->ioaddr.altstatus_addr = mem + 0xe;
  93        ap->ioaddr.ctl_addr = mem + 0xe;
  94
  95        /* start the port */
  96        ata_sff_std_ports(&ap->ioaddr);
  97
  98        /* activate host */
  99        ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
 100                                        &palmld_sht);
 101        if (ret)
 102                goto err2;
 103
 104        return ret;
 105
 106err2:
 107        gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
 108err1:
 109        return ret;
 110}
 111
 112static int palmld_pata_remove(struct platform_device *dev)
 113{
 114        ata_platform_remove_one(dev);
 115
 116        /* power down the HDD */
 117        gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0);
 118
 119        gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
 120
 121        return 0;
 122}
 123
 124static struct platform_driver palmld_pata_platform_driver = {
 125        .driver  = {
 126                .name   = DRV_NAME,
 127                .owner  = THIS_MODULE,
 128        },
 129        .probe          = palmld_pata_probe,
 130        .remove         = palmld_pata_remove,
 131};
 132
 133module_platform_driver(palmld_pata_platform_driver);
 134
 135MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
 136MODULE_DESCRIPTION("PalmLD PATA driver");
 137MODULE_LICENSE("GPL");
 138MODULE_ALIAS("platform:" DRV_NAME);
 139