···6363 tristate "ForteMedia FM801 gameport support"6464 depends on PCI65656666-config GAMEPORT_CS461X6767- tristate "Crystal SoundFusion gameport support"6868- depends on PCI6969-7066endif
-1
drivers/input/gameport/Makefile
···55# Each configuration option enables a list of files.6677obj-$(CONFIG_GAMEPORT) += gameport.o88-obj-$(CONFIG_GAMEPORT_CS461X) += cs461x.o98obj-$(CONFIG_GAMEPORT_EMU10K1) += emu10k1-gp.o109obj-$(CONFIG_GAMEPORT_FM801) += fm801-gp.o1110obj-$(CONFIG_GAMEPORT_L4) += lightning.o
-322
drivers/input/gameport/cs461x.c
···11-/*22- The all defines and part of code (such as cs461x_*) are33- contributed from ALSA 0.5.8 sources.44- See http://www.alsa-project.org/ for sources55-66- Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS461077-*/88-99-#include <asm/io.h>1010-1111-#include <linux/module.h>1212-#include <linux/ioport.h>1313-#include <linux/config.h>1414-#include <linux/init.h>1515-#include <linux/gameport.h>1616-#include <linux/slab.h>1717-#include <linux/pci.h>1818-1919-MODULE_AUTHOR("Victor Krapivin");2020-MODULE_LICENSE("GPL");2121-2222-/*2323- These options are experimental2424-2525-#define CS461X_FULL_MAP2626-*/2727-2828-2929-#ifndef PCI_VENDOR_ID_CIRRUS3030-#define PCI_VENDOR_ID_CIRRUS 0x10133131-#endif3232-#ifndef PCI_DEVICE_ID_CIRRUS_46103333-#define PCI_DEVICE_ID_CIRRUS_4610 0x60013434-#endif3535-#ifndef PCI_DEVICE_ID_CIRRUS_46123636-#define PCI_DEVICE_ID_CIRRUS_4612 0x60033737-#endif3838-#ifndef PCI_DEVICE_ID_CIRRUS_46153939-#define PCI_DEVICE_ID_CIRRUS_4615 0x60044040-#endif4141-4242-/* Registers */4343-4444-#define BA0_JSPT 0x000004804545-#define BA0_JSCTL 0x000004844646-#define BA0_JSC1 0x000004884747-#define BA0_JSC2 0x0000048C4848-#define BA0_JSIO 0x000004A04949-5050-/* Bits for JSPT */5151-5252-#define JSPT_CAX 0x000000015353-#define JSPT_CAY 0x000000025454-#define JSPT_CBX 0x000000045555-#define JSPT_CBY 0x000000085656-#define JSPT_BA1 0x000000105757-#define JSPT_BA2 0x000000205858-#define JSPT_BB1 0x000000405959-#define JSPT_BB2 0x000000806060-6161-/* Bits for JSCTL */6262-6363-#define JSCTL_SP_MASK 0x000000036464-#define JSCTL_SP_SLOW 0x000000006565-#define JSCTL_SP_MEDIUM_SLOW 0x000000016666-#define JSCTL_SP_MEDIUM_FAST 0x000000026767-#define JSCTL_SP_FAST 0x000000036868-#define JSCTL_ARE 0x000000046969-7070-/* Data register pairs masks */7171-7272-#define JSC1_Y1V_MASK 0x0000FFFF7373-#define JSC1_X1V_MASK 0xFFFF00007474-#define JSC1_Y1V_SHIFT 07575-#define JSC1_X1V_SHIFT 167676-#define JSC2_Y2V_MASK 0x0000FFFF7777-#define JSC2_X2V_MASK 0xFFFF00007878-#define JSC2_Y2V_SHIFT 07979-#define JSC2_X2V_SHIFT 168080-8181-/* JS GPIO */8282-8383-#define JSIO_DAX 0x000000018484-#define JSIO_DAY 0x000000028585-#define JSIO_DBX 0x000000048686-#define JSIO_DBY 0x000000088787-#define JSIO_AXOE 0x000000108888-#define JSIO_AYOE 0x000000208989-#define JSIO_BXOE 0x000000409090-#define JSIO_BYOE 0x000000809191-9292-/*9393- The card initialization code is obfuscated; the module cs461x9494- need to be loaded after ALSA modules initialized and something9595- played on the CS 4610 chip (see sources for details of CS46109696- initialization code from ALSA)9797-*/9898-9999-/* Card specific definitions */100100-101101-#define CS461X_BA0_SIZE 0x2000102102-#define CS461X_BA1_DATA0_SIZE 0x3000103103-#define CS461X_BA1_DATA1_SIZE 0x3800104104-#define CS461X_BA1_PRG_SIZE 0x7000105105-#define CS461X_BA1_REG_SIZE 0x0100106106-107107-#define BA1_SP_DMEM0 0x00000000108108-#define BA1_SP_DMEM1 0x00010000109109-#define BA1_SP_PMEM 0x00020000110110-#define BA1_SP_REG 0x00030000111111-112112-#define BA1_DWORD_SIZE (13 * 1024 + 512)113113-#define BA1_MEMORY_COUNT 3114114-115115-/*116116- Only one CS461x card is still suppoted; the code requires117117- redesign to avoid this limitatuion.118118-*/119119-120120-static unsigned long ba0_addr;121121-static unsigned int __iomem *ba0;122122-123123-#ifdef CS461X_FULL_MAP124124-static unsigned long ba1_addr;125125-static union ba1_t {126126- struct {127127- unsigned int __iomem *data0;128128- unsigned int __iomem *data1;129129- unsigned int __iomem *pmem;130130- unsigned int __iomem *reg;131131- } name;132132- unsigned int __iomem *idx[4];133133-} ba1;134134-135135-static void cs461x_poke(unsigned long reg, unsigned int val)136136-{137137- writel(val, &ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);138138-}139139-140140-static unsigned int cs461x_peek(unsigned long reg)141141-{142142- return readl(&ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);143143-}144144-145145-#endif146146-147147-static void cs461x_pokeBA0(unsigned long reg, unsigned int val)148148-{149149- writel(val, &ba0[reg >> 2]);150150-}151151-152152-static unsigned int cs461x_peekBA0(unsigned long reg)153153-{154154- return readl(&ba0[reg >> 2]);155155-}156156-157157-static int cs461x_free(struct pci_dev *pdev)158158-{159159- struct gameport *port = pci_get_drvdata(pdev);160160-161161- if (port)162162- gameport_unregister_port(port);163163-164164- if (ba0) iounmap(ba0);165165-#ifdef CS461X_FULL_MAP166166- if (ba1.name.data0) iounmap(ba1.name.data0);167167- if (ba1.name.data1) iounmap(ba1.name.data1);168168- if (ba1.name.pmem) iounmap(ba1.name.pmem);169169- if (ba1.name.reg) iounmap(ba1.name.reg);170170-#endif171171- return 0;172172-}173173-174174-static void cs461x_gameport_trigger(struct gameport *gameport)175175-{176176- cs461x_pokeBA0(BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);177177-}178178-179179-static unsigned char cs461x_gameport_read(struct gameport *gameport)180180-{181181- return cs461x_peekBA0(BA0_JSPT); //inb(gameport->io);182182-}183183-184184-static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)185185-{186186- unsigned js1, js2, jst;187187-188188- js1 = cs461x_peekBA0(BA0_JSC1);189189- js2 = cs461x_peekBA0(BA0_JSC2);190190- jst = cs461x_peekBA0(BA0_JSPT);191191-192192- *buttons = (~jst >> 4) & 0x0F;193193-194194- axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;195195- axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;196196- axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;197197- axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;198198-199199- for(jst=0;jst<4;++jst)200200- if(axes[jst]==0xFFFF) axes[jst] = -1;201201- return 0;202202-}203203-204204-static int cs461x_gameport_open(struct gameport *gameport, int mode)205205-{206206- switch (mode) {207207- case GAMEPORT_MODE_COOKED:208208- case GAMEPORT_MODE_RAW:209209- return 0;210210- default:211211- return -1;212212- }213213- return 0;214214-}215215-216216-static struct pci_device_id cs461x_pci_tbl[] = {217217- { PCI_VENDOR_ID_CIRRUS, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4610 */218218- { PCI_VENDOR_ID_CIRRUS, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4612 */219219- { PCI_VENDOR_ID_CIRRUS, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4615 */220220- { 0, }221221-};222222-MODULE_DEVICE_TABLE(pci, cs461x_pci_tbl);223223-224224-static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)225225-{226226- int rc;227227- struct gameport* port;228228-229229- rc = pci_enable_device(pdev);230230- if (rc) {231231- printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",232232- pdev->bus->number, pdev->devfn, rc);233233- return rc;234234- }235235-236236- ba0_addr = pci_resource_start(pdev, 0);237237-#ifdef CS461X_FULL_MAP238238- ba1_addr = pci_resource_start(pdev, 1);239239-#endif240240- if (ba0_addr == 0 || ba0_addr == ~0241241-#ifdef CS461X_FULL_MAP242242- || ba1_addr == 0 || ba1_addr == ~0243243-#endif244244- ) {245245- printk(KERN_ERR "cs461x: wrong address - ba0 = 0x%lx\n", ba0_addr);246246-#ifdef CS461X_FULL_MAP247247- printk(KERN_ERR "cs461x: wrong address - ba1 = 0x%lx\n", ba1_addr);248248-#endif249249- cs461x_free(pdev);250250- return -ENOMEM;251251- }252252-253253- ba0 = ioremap(ba0_addr, CS461X_BA0_SIZE);254254-#ifdef CS461X_FULL_MAP255255- ba1.name.data0 = ioremap(ba1_addr + BA1_SP_DMEM0, CS461X_BA1_DATA0_SIZE);256256- ba1.name.data1 = ioremap(ba1_addr + BA1_SP_DMEM1, CS461X_BA1_DATA1_SIZE);257257- ba1.name.pmem = ioremap(ba1_addr + BA1_SP_PMEM, CS461X_BA1_PRG_SIZE);258258- ba1.name.reg = ioremap(ba1_addr + BA1_SP_REG, CS461X_BA1_REG_SIZE);259259-260260- if (ba0 == NULL || ba1.name.data0 == NULL ||261261- ba1.name.data1 == NULL || ba1.name.pmem == NULL ||262262- ba1.name.reg == NULL) {263263- cs461x_free(pdev);264264- return -ENOMEM;265265- }266266-#else267267- if (ba0 == NULL) {268268- cs461x_free(pdev);269269- return -ENOMEM;270270- }271271-#endif272272-273273- if (!(port = gameport_allocate_port())) {274274- printk(KERN_ERR "cs461x: Memory allocation failed\n");275275- cs461x_free(pdev);276276- return -ENOMEM;277277- }278278-279279- pci_set_drvdata(pdev, port);280280-281281- port->open = cs461x_gameport_open;282282- port->trigger = cs461x_gameport_trigger;283283- port->read = cs461x_gameport_read;284284- port->cooked_read = cs461x_gameport_cooked_read;285285-286286- gameport_set_name(port, "CS416x");287287- gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev));288288- port->dev.parent = &pdev->dev;289289-290290- cs461x_pokeBA0(BA0_JSIO, 0xFF); // ?291291- cs461x_pokeBA0(BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);292292-293293- gameport_register_port(port);294294-295295- return 0;296296-}297297-298298-static void __devexit cs461x_pci_remove(struct pci_dev *pdev)299299-{300300- cs461x_free(pdev);301301-}302302-303303-static struct pci_driver cs461x_pci_driver = {304304- .name = "CS461x_gameport",305305- .id_table = cs461x_pci_tbl,306306- .probe = cs461x_pci_probe,307307- .remove = __devexit_p(cs461x_pci_remove),308308-};309309-310310-static int __init cs461x_init(void)311311-{312312- return pci_register_driver(&cs461x_pci_driver);313313-}314314-315315-static void __exit cs461x_exit(void)316316-{317317- pci_unregister_driver(&cs461x_pci_driver);318318-}319319-320320-module_init(cs461x_init);321321-module_exit(cs461x_exit);322322-