^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * pata_sil680.c - SIL680 PATA for new ATA layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) 2005 Red Hat Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * based upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2003 Red Hat <alan@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * May be copied or modified under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Documentation publicly available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * If you have strange problems with nVidia chipset systems please
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * see the SI support documentation and update your system BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * If we know all our devices are LBA28 (or LBA28 sized) we could use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * the command fifo mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/libata.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DRV_NAME "pata_sil680"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DRV_VERSION "0.4.9"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define SIL680_MMIO_BAR 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * sil680_selreg - return register base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @ap: ATA interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * @r: config offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Turn a config register offset into the right address in PCI space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * to access the control register in question.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Thankfully this is a configuration operation so isn't performance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * criticial.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static unsigned long sil680_selreg(struct ata_port *ap, int r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned long base = 0xA0 + r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) base += (ap->port_no << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * sil680_seldev - return register base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @ap: ATA interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @r: config offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Turn a config register offset into the right address in PCI space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * to access the control register in question including accounting for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * the unit shift.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long base = 0xA0 + r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) base += (ap->port_no << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) base |= adev->devno ? 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * sil680_cable_detect - cable detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @ap: ATA port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Perform cable detection. The SIL680 stores this in PCI config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * space for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int sil680_cable_detect(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct pci_dev *pdev = to_pci_dev(ap->host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long addr = sil680_selreg(ap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 ata66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) pci_read_config_byte(pdev, addr, &ata66);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (ata66 & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return ATA_CBL_PATA80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ATA_CBL_PATA40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * sil680_set_piomode - set PIO mode data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @ap: ATA interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @adev: ATA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Program the SIL680 registers for PIO mode. Note that the task speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * registers are shared between the devices so we must pick the lowest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * mode for command work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const u16 speed_p[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static const u16 speed_t[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned long tfaddr = sil680_selreg(ap, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned long addr = sil680_seldev(ap, adev, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned long addr_mask = 0x80 + 4 * ap->port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct pci_dev *pdev = to_pci_dev(ap->host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int pio = adev->pio_mode - XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int lowest_pio = pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int port_shift = 4 * adev->devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct ata_device *pair = ata_dev_pair(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (pair != NULL && adev->pio_mode > pair->pio_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) lowest_pio = pair->pio_mode - XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) pci_write_config_word(pdev, addr, speed_p[pio]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) pci_read_config_word(pdev, tfaddr-2, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) pci_read_config_byte(pdev, addr_mask, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) reg &= ~0x0200; /* Clear IORDY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mode &= ~(3 << port_shift); /* Clear IORDY and DMA bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (ata_pio_need_iordy(adev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) reg |= 0x0200; /* Enable IORDY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mode |= 1 << port_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) pci_write_config_word(pdev, tfaddr-2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pci_write_config_byte(pdev, addr_mask, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * sil680_set_dmamode - set DMA mode data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @ap: ATA interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @adev: ATA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * Program the MWDMA/UDMA modes for the sil680 chipset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * The MWDMA mode values are pulled from a lookup table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * while the chipset uses mode number for UDMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static const u8 ultra_table[2][7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static const u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct pci_dev *pdev = to_pci_dev(ap->host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned long ma = sil680_seldev(ap, adev, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned long ua = sil680_seldev(ap, adev, 0x0C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned long addr_mask = 0x80 + 4 * ap->port_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int port_shift = adev->devno * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u8 scsc, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u16 multi, ultra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pci_read_config_byte(pdev, 0x8A, &scsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pci_read_config_byte(pdev, addr_mask, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pci_read_config_word(pdev, ma, &multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pci_read_config_word(pdev, ua, &ultra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* Mask timing bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ultra &= ~0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mode &= ~(0x03 << port_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Extract scsc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) scsc = (scsc & 0x30) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (adev->dma_mode >= XFER_UDMA_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) multi = 0x10C1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mode |= (0x03 << port_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) multi = dma_table[adev->dma_mode - XFER_MW_DMA_0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) mode |= (0x02 << port_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) pci_write_config_byte(pdev, addr_mask, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) pci_write_config_word(pdev, ma, multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pci_write_config_word(pdev, ua, ultra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * sil680_sff_exec_command - issue ATA command to host controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * @ap: port to which command is being issued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * @tf: ATA taskfile register set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Issues ATA command, with proper synchronization with interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * handler / other threads. Use our MMIO space for PCI posting to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * a hideously slow cycle all the way to the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * LOCKING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * spin_lock_irqsave(host lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void sil680_sff_exec_command(struct ata_port *ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) const struct ata_taskfile *tf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) iowrite8(tf->command, ap->ioaddr.command_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static bool sil680_sff_irq_check(struct ata_port *ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct pci_dev *pdev = to_pci_dev(ap->host->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned long addr = sil680_selreg(ap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pci_read_config_byte(pdev, addr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return val & 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static struct scsi_host_template sil680_sht = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ATA_BMDMA_SHT(DRV_NAME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static struct ata_port_operations sil680_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .inherits = &ata_bmdma32_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .sff_exec_command = sil680_sff_exec_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .sff_irq_check = sil680_sff_irq_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .cable_detect = sil680_cable_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .set_piomode = sil680_set_piomode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .set_dmamode = sil680_set_dmamode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * sil680_init_chip - chip setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @pdev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Perform all the chip setup which must be done both when the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * is powered up on boot and when we resume in case we resumed from RAM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * Returns the final clock settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u8 tmpbyte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* FIXME: double check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pdev->revision ? 1 : 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) pci_write_config_byte(pdev, 0x80, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pci_write_config_byte(pdev, 0x84, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pci_read_config_byte(pdev, 0x8A, &tmpbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) tmpbyte & 1, tmpbyte & 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *try_mmio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #ifdef CONFIG_PPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (machine_is(cell))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) switch (tmpbyte & 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* 133 clock attempt to force it on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case 0x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* if clocking is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* 133 clock attempt to force it on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* 133 already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* BIOS set PCI x2 clocking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pci_read_config_byte(pdev, 0x8A, &tmpbyte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) tmpbyte & 1, tmpbyte & 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) pci_write_config_byte(pdev, 0xA1, 0x72);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pci_write_config_word(pdev, 0xA2, 0x328A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) pci_write_config_dword(pdev, 0xA4, 0x62DD62DD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pci_write_config_dword(pdev, 0xA8, 0x43924392);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) pci_write_config_dword(pdev, 0xAC, 0x40094009);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pci_write_config_byte(pdev, 0xB1, 0x72);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) pci_write_config_word(pdev, 0xB2, 0x328A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) pci_write_config_dword(pdev, 0xB4, 0x62DD62DD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pci_write_config_dword(pdev, 0xB8, 0x43924392);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) pci_write_config_dword(pdev, 0xBC, 0x40094009);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) switch (tmpbyte & 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) printk(KERN_INFO "sil680: 100MHz clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) printk(KERN_INFO "sil680: 133MHz clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) printk(KERN_INFO "sil680: Using PCI clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* This last case is _NOT_ ok */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case 0x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) printk(KERN_ERR "sil680: Clock disabled ?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return tmpbyte & 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static const struct ata_port_info info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .flags = ATA_FLAG_SLAVE_POSS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .pio_mask = ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .mwdma_mask = ATA_MWDMA2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .udma_mask = ATA_UDMA6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .port_ops = &sil680_port_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static const struct ata_port_info info_slow = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .flags = ATA_FLAG_SLAVE_POSS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .pio_mask = ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .mwdma_mask = ATA_MWDMA2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .udma_mask = ATA_UDMA5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .port_ops = &sil680_port_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) const struct ata_port_info *ppi[] = { &info, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct ata_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) void __iomem *mmio_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int rc, try_mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ata_print_version_once(&pdev->dev, DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) rc = pcim_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) switch (sil680_init_chip(pdev, &try_mmio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ppi[0] = &info_slow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case 0x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!try_mmio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) goto use_ioports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Try to acquire MMIO resources and fallback to PIO if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * that fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) goto use_ioports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* Allocate host and set it up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) host->iomap = pcim_iomap_table(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Setup DMA masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) rc = dma_set_mask_and_coherent(&pdev->dev, ATA_DMA_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Get MMIO base and initialize port addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mmio_base = host->iomap[SIL680_MMIO_BAR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ata_sff_std_ports(&host->ports[0]->ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ata_sff_std_ports(&host->ports[1]->ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Register & activate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) IRQF_SHARED, &sil680_sht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) use_ioports:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return ata_pci_bmdma_init_one(pdev, ppi, &sil680_sht, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int sil680_reinit_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct ata_host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int try_mmio, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) rc = ata_pci_device_do_resume(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) sil680_init_chip(pdev, &try_mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ata_host_resume(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static const struct pci_device_id sil680[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static struct pci_driver sil680_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .id_table = sil680,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .probe = sil680_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .remove = ata_pci_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .suspend = ata_pci_device_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .resume = sil680_reinit_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) module_pci_driver(sil680_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) MODULE_AUTHOR("Alan Cox");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) MODULE_DESCRIPTION("low-level driver for SI680 PATA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) MODULE_DEVICE_TABLE(pci, sil680);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) MODULE_VERSION(DRV_VERSION);