2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
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 >
*/
# 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>
2018-11-13 16:01:02 +03:00
# include <linux/gpio/consumer.h>
2009-05-21 16:11:05 +04:00
# include <scsi/scsi_host.h>
# include <mach/palmld.h>
# define DRV_NAME "pata_palmld"
2018-12-05 11:49:11 +03:00
struct palmld_pata {
struct ata_host * host ;
struct gpio_desc * power ;
struct gpio_desc * reset ;
} ;
2011-01-15 21:19:05 +03:00
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 ,
2018-07-11 18:21:05 +03:00
. sff_data_xfer = ata_sff_data_xfer32 ,
2009-05-21 16:11:05 +04:00
. cable_detect = ata_cable_40wire ,
} ;
2012-12-22 01:19:58 +04:00
static int palmld_pata_probe ( struct platform_device * pdev )
2009-05-21 16:11:05 +04:00
{
2018-12-05 11:49:11 +03:00
struct palmld_pata * lda ;
2009-05-21 16:11:05 +04:00
struct ata_port * ap ;
void __iomem * mem ;
2018-11-13 16:01:02 +03:00
struct device * dev = & pdev - > dev ;
2009-05-21 16:11:05 +04:00
int ret ;
2018-12-05 11:49:11 +03:00
lda = devm_kzalloc ( dev , sizeof ( * lda ) , GFP_KERNEL ) ;
if ( ! lda )
return - ENOMEM ;
2009-05-21 16:11:05 +04:00
/* allocate host */
2018-12-05 11:49:11 +03:00
lda - > host = ata_host_alloc ( dev , 1 ) ;
if ( ! lda - > host )
2018-11-13 16:01:02 +03:00
return - ENOMEM ;
2009-05-21 16:11:05 +04:00
/* remap drive's physical memory address */
2018-11-13 16:01:02 +03:00
mem = devm_ioremap ( dev , PALMLD_IDE_PHYS , 0x1000 ) ;
if ( ! mem )
return - ENOMEM ;
/* request and activate power and reset GPIOs */
2018-12-05 11:49:11 +03:00
lda - > power = devm_gpiod_get ( dev , " power " , GPIOD_OUT_HIGH ) ;
if ( IS_ERR ( lda - > power ) )
return PTR_ERR ( lda - > power ) ;
lda - > reset = devm_gpiod_get ( dev , " reset " , GPIOD_OUT_HIGH ) ;
if ( IS_ERR ( lda - > reset ) ) {
gpiod_set_value ( lda - > power , 0 ) ;
return PTR_ERR ( lda - > reset ) ;
2011-01-15 21:19:05 +03:00
}
2009-05-21 16:11:05 +04:00
2018-11-13 16:01:02 +03:00
/* Assert reset to reset the drive */
2018-12-05 11:49:11 +03:00
gpiod_set_value ( lda - > reset , 1 ) ;
2009-05-21 16:11:05 +04:00
msleep ( 30 ) ;
2018-12-05 11:49:11 +03:00
gpiod_set_value ( lda - > reset , 0 ) ;
2009-05-21 16:11:05 +04:00
msleep ( 30 ) ;
/* setup the ata port */
2018-12-05 11:49:11 +03:00
ap = lda - > host - > ports [ 0 ] ;
2009-05-21 16:11:05 +04:00
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 */
2018-12-05 11:49:11 +03:00
ret = ata_host_activate ( lda - > host , 0 , NULL , IRQF_TRIGGER_RISING ,
& palmld_sht ) ;
2018-11-13 16:01:02 +03:00
/* power down on failure */
2018-12-05 11:49:11 +03:00
if ( ret ) {
gpiod_set_value ( lda - > power , 0 ) ;
return ret ;
}
platform_set_drvdata ( pdev , lda ) ;
return 0 ;
2009-05-21 16:11:05 +04:00
}
2018-12-05 11:49:11 +03:00
static int palmld_pata_remove ( struct platform_device * pdev )
2009-05-21 16:11:05 +04:00
{
2018-12-05 11:49:11 +03:00
struct palmld_pata * lda = platform_get_drvdata ( pdev ) ;
ata_platform_remove_one ( pdev ) ;
2009-05-21 16:11:05 +04:00
/* power down the HDD */
2018-12-05 11:49:11 +03:00
gpiod_set_value ( lda - > power , 0 ) ;
2009-05-21 16:11:05 +04:00
return 0 ;
}
static struct platform_driver palmld_pata_platform_driver = {
. driver = {
. name = DRV_NAME ,
} ,
. probe = palmld_pata_probe ,
2012-12-22 01:19:58 +04:00
. remove = palmld_pata_remove ,
2009-05-21 16:11:05 +04:00
} ;
2011-11-27 10:44:26 +04:00
module_platform_driver ( palmld_pata_platform_driver ) ;
2009-05-21 16:11:05 +04:00
MODULE_AUTHOR ( " Marek Vasut <marek.vasut@gmail.com> " ) ;
MODULE_DESCRIPTION ( " PalmLD PATA driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform: " DRV_NAME ) ;