2009-05-21 16:11:05 +04:00
/*
* drivers / ata / pata_palmld . c
*
* Driver for IDE channel in Palm LifeDrive
*
* Based on research of :
* Alex Osborne < ato @ meshy . org >
*
* Rewrite for mainline :
* Marek Vasut < marek . vasut @ gmail . com >
*
* Rewritten version based on pata_ixp4xx_cf . c :
* ixp4xx PATA / Compact Flash driver
* Copyright ( C ) 2006 - 07 Tower Technologies
* Author : Alessandro Zummo < a . zummo @ towertech . it >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/libata.h>
# include <linux/irq.h>
# include <linux/platform_device.h>
# include <linux/delay.h>
# include <linux/gpio.h>
# include <scsi/scsi_host.h>
# include <mach/palmld.h>
# define DRV_NAME "pata_palmld"
2011-01-15 21:19:05 +03:00
static struct gpio palmld_hdd_gpios [ ] = {
{ GPIO_NR_PALMLD_IDE_PWEN , GPIOF_INIT_HIGH , " HDD Power " } ,
{ GPIO_NR_PALMLD_IDE_RESET , GPIOF_INIT_LOW , " HDD Reset " } ,
} ;
2009-05-21 16:11:05 +04:00
static struct scsi_host_template palmld_sht = {
ATA_PIO_SHT ( DRV_NAME ) ,
} ;
static struct ata_port_operations palmld_port_ops = {
. inherits = & ata_sff_port_ops ,
. sff_data_xfer = ata_sff_data_xfer_noirq ,
. cable_detect = ata_cable_40wire ,
} ;
static __devinit int palmld_pata_probe ( struct platform_device * pdev )
{
struct ata_host * host ;
struct ata_port * ap ;
void __iomem * mem ;
int ret ;
/* allocate host */
host = ata_host_alloc ( & pdev - > dev , 1 ) ;
2011-01-15 21:19:05 +03:00
if ( ! host ) {
ret = - ENOMEM ;
goto err1 ;
}
2009-05-21 16:11:05 +04:00
/* remap drive's physical memory address */
mem = devm_ioremap ( & pdev - > dev , PALMLD_IDE_PHYS , 0x1000 ) ;
2011-01-15 21:19:05 +03:00
if ( ! mem ) {
ret = - ENOMEM ;
goto err1 ;
}
2009-05-21 16:11:05 +04:00
/* request and activate power GPIO, IRQ GPIO */
2011-01-15 21:19:05 +03:00
ret = gpio_request_array ( palmld_hdd_gpios ,
ARRAY_SIZE ( palmld_hdd_gpios ) ) ;
2009-05-21 16:11:05 +04:00
if ( ret )
goto err1 ;
/* reset the drive */
gpio_set_value ( GPIO_NR_PALMLD_IDE_RESET , 0 ) ;
msleep ( 30 ) ;
gpio_set_value ( GPIO_NR_PALMLD_IDE_RESET , 1 ) ;
msleep ( 30 ) ;
/* setup the ata port */
ap = host - > ports [ 0 ] ;
ap - > ops = & palmld_port_ops ;
ap - > pio_mask = ATA_PIO4 ;
2011-02-04 22:05:48 +03:00
ap - > flags | = ATA_FLAG_PIO_POLLING ;
2009-05-21 16:11:05 +04:00
/* memory mapping voodoo */
ap - > ioaddr . cmd_addr = mem + 0x10 ;
ap - > ioaddr . altstatus_addr = mem + 0xe ;
ap - > ioaddr . ctl_addr = mem + 0xe ;
/* start the port */
ata_sff_std_ports ( & ap - > ioaddr ) ;
/* activate host */
2011-01-15 21:19:05 +03:00
ret = ata_host_activate ( host , 0 , NULL , IRQF_TRIGGER_RISING ,
2009-05-21 16:11:05 +04:00
& palmld_sht ) ;
2011-01-15 21:19:05 +03:00
if ( ret )
goto err2 ;
return ret ;
2009-05-21 16:11:05 +04:00
err2 :
2011-01-15 21:19:05 +03:00
gpio_free_array ( palmld_hdd_gpios , ARRAY_SIZE ( palmld_hdd_gpios ) ) ;
2009-05-21 16:11:05 +04:00
err1 :
return ret ;
}
static __devexit int palmld_pata_remove ( struct platform_device * dev )
{
struct ata_host * host = platform_get_drvdata ( dev ) ;
ata_host_detach ( host ) ;
/* power down the HDD */
gpio_set_value ( GPIO_NR_PALMLD_IDE_PWEN , 0 ) ;
2011-01-15 21:19:05 +03:00
gpio_free_array ( palmld_hdd_gpios , ARRAY_SIZE ( palmld_hdd_gpios ) ) ;
2009-05-21 16:11:05 +04:00
return 0 ;
}
static struct platform_driver palmld_pata_platform_driver = {
. driver = {
. name = DRV_NAME ,
. owner = THIS_MODULE ,
} ,
. probe = palmld_pata_probe ,
. remove = __devexit_p ( palmld_pata_remove ) ,
} ;
static int __init palmld_pata_init ( void )
{
return platform_driver_register ( & palmld_pata_platform_driver ) ;
}
static void __exit palmld_pata_exit ( void )
{
platform_driver_unregister ( & palmld_pata_platform_driver ) ;
}
MODULE_AUTHOR ( " Marek Vasut <marek.vasut@gmail.com> " ) ;
MODULE_DESCRIPTION ( " PalmLD PATA driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform: " DRV_NAME ) ;
module_init ( palmld_pata_init ) ;
module_exit ( palmld_pata_exit ) ;