2005-04-17 02:20:36 +04:00
/*
* IDE Chipset driver for the Compaq TriFlex IDE controller .
*
* Known to work with the Compaq Workstation 5 x00 series .
*
* Copyright ( C ) 2002 Hewlett - Packard Development Group , L . P .
* Author : Torben Mathiasen < torben . mathiasen @ hp . com >
*
* 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 .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* Loosely based on the piix & svwks drivers .
*
* Documentation :
2011-03-31 05:57:33 +04:00
* Not publicly available .
2005-04-17 02:20:36 +04:00
*/
# include <linux/types.h>
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/pci.h>
# include <linux/ide.h>
# include <linux/init.h>
2008-07-25 00:53:32 +04:00
# define DRV_NAME "triflex"
2010-01-19 12:45:29 +03:00
static void triflex_set_mode ( ide_hwif_t * hwif , ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2008-02-02 01:09:31 +03:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
2005-04-17 02:20:36 +04:00
u32 triflex_timings = 0 ;
2008-10-13 23:39:40 +04:00
u16 timing = 0 ;
u8 channel_offset = hwif - > channel ? 0x74 : 0x70 , unit = drive - > dn & 1 ;
2005-04-17 02:20:36 +04:00
pci_read_config_dword ( dev , channel_offset , & triflex_timings ) ;
2008-10-13 23:39:40 +04:00
2010-01-19 12:45:29 +03:00
switch ( drive - > dma_mode ) {
2005-04-17 02:20:36 +04:00
case XFER_MW_DMA_2 :
timing = 0x0103 ;
break ;
case XFER_MW_DMA_1 :
timing = 0x0203 ;
break ;
case XFER_MW_DMA_0 :
timing = 0x0808 ;
break ;
case XFER_SW_DMA_2 :
case XFER_SW_DMA_1 :
case XFER_SW_DMA_0 :
timing = 0x0f0f ;
break ;
case XFER_PIO_4 :
timing = 0x0202 ;
break ;
case XFER_PIO_3 :
timing = 0x0204 ;
break ;
case XFER_PIO_2 :
timing = 0x0404 ;
break ;
case XFER_PIO_1 :
timing = 0x0508 ;
break ;
case XFER_PIO_0 :
timing = 0x0808 ;
break ;
}
triflex_timings & = ~ ( 0xFFFF < < ( 16 * unit ) ) ;
triflex_timings | = ( timing < < ( 16 * unit ) ) ;
pci_write_config_dword ( dev , channel_offset , triflex_timings ) ;
}
2010-01-19 12:44:41 +03:00
static void triflex_set_pio_mode ( ide_hwif_t * hwif , ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2010-01-19 12:45:29 +03:00
drive - > dma_mode = drive - > pio_mode ;
triflex_set_mode ( hwif , drive ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-27 00:25:14 +04:00
static const struct ide_port_ops triflex_port_ops = {
. set_pio_mode = triflex_set_pio_mode ,
. set_dma_mode = triflex_set_mode ,
} ;
2005-04-17 02:20:36 +04:00
2012-12-22 01:21:03 +04:00
static const struct ide_port_info triflex_device = {
2008-07-25 00:53:32 +04:00
. name = DRV_NAME ,
2005-04-17 02:20:36 +04:00
. enablebits = { { 0x80 , 0x01 , 0x01 } , { 0x80 , 0x02 , 0x02 } } ,
2008-04-27 00:25:14 +04:00
. port_ops = & triflex_port_ops ,
2007-07-20 03:11:59 +04:00
. pio_mask = ATA_PIO4 ,
2007-10-19 02:30:07 +04:00
. swdma_mask = ATA_SWDMA2 ,
. mwdma_mask = ATA_MWDMA2 ,
2005-04-17 02:20:36 +04:00
} ;
2012-12-22 01:21:03 +04:00
static int triflex_init_one ( struct pci_dev * dev , const struct pci_device_id * id )
2005-04-17 02:20:36 +04:00
{
2008-07-25 00:53:14 +04:00
return ide_pci_init_one ( dev , & triflex_device , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2007-10-17 00:29:56 +04:00
static const struct pci_device_id triflex_pci_tbl [ ] = {
{ PCI_VDEVICE ( COMPAQ , PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE ) , 0 } ,
2005-04-17 02:20:36 +04:00
{ 0 , } ,
} ;
MODULE_DEVICE_TABLE ( pci , triflex_pci_tbl ) ;
2011-10-12 08:31:51 +04:00
# ifdef CONFIG_PM
static int triflex_ide_pci_suspend ( struct pci_dev * dev , pm_message_t state )
{
/*
* We must not disable or powerdown the device .
* APM bios refuses to suspend if IDE is not accessible .
*/
pci_save_state ( dev ) ;
return 0 ;
}
# else
# define triflex_ide_pci_suspend NULL
# endif
2008-10-13 23:39:41 +04:00
static struct pci_driver triflex_pci_driver = {
2005-04-17 02:20:36 +04:00
. name = " TRIFLEX_IDE " ,
. id_table = triflex_pci_tbl ,
. probe = triflex_init_one ,
2008-07-25 00:53:26 +04:00
. remove = ide_pci_remove ,
2011-10-12 08:31:51 +04:00
. suspend = triflex_ide_pci_suspend ,
2008-10-11 00:39:32 +04:00
. resume = ide_pci_resume ,
2005-04-17 02:20:36 +04:00
} ;
2007-01-27 15:46:56 +03:00
static int __init triflex_ide_init ( void )
2005-04-17 02:20:36 +04:00
{
2008-10-13 23:39:41 +04:00
return ide_pci_register_driver ( & triflex_pci_driver ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-25 00:53:26 +04:00
static void __exit triflex_ide_exit ( void )
{
2008-10-13 23:39:41 +04:00
pci_unregister_driver ( & triflex_pci_driver ) ;
2008-07-25 00:53:26 +04:00
}
2005-04-17 02:20:36 +04:00
module_init ( triflex_ide_init ) ;
2008-07-25 00:53:26 +04:00
module_exit ( triflex_ide_exit ) ;
2005-04-17 02:20:36 +04:00
MODULE_AUTHOR ( " Torben Mathiasen " ) ;
MODULE_DESCRIPTION ( " PCI driver module for Compaq Triflex IDE " ) ;
MODULE_LICENSE ( " GPL " ) ;