10a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck/* 20a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * Copyright (C) 2008-2010 30a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * 40a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * - Kurt Van Dijck, EIA Electronics 50a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * 60a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * This program is free software; you can redistribute it and/or modify 70a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * it under the terms of the version 2 of the GNU General Public License 80a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * as published by the Free Software Foundation 90a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * 100a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * This program is distributed in the hope that it will be useful, 110a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * but WITHOUT ANY WARRANTY; without even the implied warranty of 120a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 130a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * GNU General Public License for more details. 140a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * 150a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * You should have received a copy of the GNU General Public License 160a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * along with this program; if not, write to the Free Software 170a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 180a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck */ 190a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 200a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck#include <linux/module.h> 210a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck#include <linux/kernel.h> 2269e6ed186009ce86cbf5da95f45227064134d694Randy Dunlap#include <linux/slab.h> 230a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 240a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck#include <pcmcia/cistpl.h> 250a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck#include <pcmcia/ds.h> 260a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 270a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck#include "softing_platform.h" 280a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 290a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic int softingcs_index; 300a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic spinlock_t softingcs_index_lock; 310a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 320a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic int softingcs_reset(struct platform_device *pdev, int v); 330a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic int softingcs_enable_irq(struct platform_device *pdev, int v); 340a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 350a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck/* 360a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * platform_data descriptions 370a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck */ 380a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck#define MHZ (1000*1000) 390a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic const struct softing_platform_data softingcs_platform_data[] = { 400a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 410a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "CANcard", 420a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x001, 430a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 1, 440a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 450a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, 460a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x0800, 470a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, 480a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, 490a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, 500a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 510a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = softingcs_enable_irq, 520a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 530a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "CANcard-NEC", 540a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x002, 550a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 1, 560a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 570a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, 580a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x0800, 590a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, 600a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, 610a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, 620a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 630a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = softingcs_enable_irq, 640a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 650a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "CANcard-SJA", 660a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x004, 670a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 1, 680a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 690a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, 700a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x0800, 710a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, 720a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, 730a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, 740a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 750a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = softingcs_enable_irq, 760a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 770a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "CANcard-2", 780a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x005, 790a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 2, 800a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 810a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, 820a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x1000, 830a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, 840a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, 850a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, 860a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 870a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = NULL, 880a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 890a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "Vector-CANcard", 900a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x081, 910a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 1, 920a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 930a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, 940a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x0800, 950a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, 960a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, 970a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, 980a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 990a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = softingcs_enable_irq, 1000a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 1010a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "Vector-CANcard-SJA", 1020a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x084, 1030a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 1, 1040a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 1050a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, 1060a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x0800, 1070a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, 1080a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, 1090a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, 1100a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 1110a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = softingcs_enable_irq, 1120a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 1130a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "Vector-CANcard-2", 1140a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x085, 1150a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 2, 1160a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 1170a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, 1180a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x1000, 1190a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, 1200a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, 1210a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, 1220a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 1230a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = NULL, 1240a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 1250a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "EDICcard-NEC", 1260a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x102, 1270a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 1, 1280a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 1290a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, 1300a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x0800, 1310a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, 1320a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, 1330a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, 1340a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 1350a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = softingcs_enable_irq, 1360a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 1370a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "EDICcard-2", 1380a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .manf = 0x0168, .prod = 0x105, 1390a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .generation = 2, 1400a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .nbus = 2, 1410a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, 1420a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .dpram_size = 0x1000, 1430a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, 1440a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, 1450a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, 1460a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .reset = softingcs_reset, 1470a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .enable_irq = NULL, 1480a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, { 1490a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 0, 0, 1500a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}, 1510a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}; 1520a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1530a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "bcard.bin"); 1540a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "ldcard.bin"); 1550a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "cancard.bin"); 1560a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "cansja.bin"); 1570a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1580a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "bcard2.bin"); 1590a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "ldcard2.bin"); 1600a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_FIRMWARE(fw_dir "cancrd2.bin"); 1610a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1620a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic __devinit const struct softing_platform_data 1630a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck*softingcs_find_platform_data(unsigned int manf, unsigned int prod) 1640a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 1650a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck const struct softing_platform_data *lp; 1660a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1670a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck for (lp = softingcs_platform_data; lp->manf; ++lp) { 1680a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if ((lp->manf == manf) && (lp->prod == prod)) 1690a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return lp; 1700a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck } 1710a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return NULL; 1720a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 1730a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1740a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck/* 1750a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * platformdata callbacks 1760a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck */ 1770a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic int softingcs_reset(struct platform_device *pdev, int v) 1780a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 1790a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); 1800a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1810a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20); 1820a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20); 1830a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 1840a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1850a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic int softingcs_enable_irq(struct platform_device *pdev, int v) 1860a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 1870a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); 1880a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1890a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0); 1900a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0); 1910a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 1920a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 1930a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck/* 1940a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * pcmcia check 1950a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck */ 1960a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic __devinit int softingcs_probe_config(struct pcmcia_device *pcmcia, 1970a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck void *priv_data) 1980a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 1990a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct softing_platform_data *pdat = priv_data; 2000a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct resource *pres; 2010a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck int memspeed = 0; 2020a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2030a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck WARN_ON(!pdat); 2040a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pres = pcmcia->resource[PCMCIA_IOMEM_0]; 2050a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (resource_size(pres) < 0x1000) 2060a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return -ERANGE; 2070a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2080a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; 2090a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (pdat->generation < 2) { 2100a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8; 2110a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck memspeed = 3; 2120a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck } else { 2130a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pres->flags |= WIN_DATA_WIDTH_16; 2140a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck } 2150a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return pcmcia_request_window(pcmcia, pres, memspeed); 2160a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 2170a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2180a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic __devexit void softingcs_remove(struct pcmcia_device *pcmcia) 2190a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 2200a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct platform_device *pdev = pcmcia->priv; 2210a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2220a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* free bits */ 2230a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck platform_device_unregister(pdev); 2240a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* release pcmcia stuff */ 2250a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pcmcia_disable_device(pcmcia); 2260a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 2270a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2280a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck/* 2290a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * platform_device wrapper 2300a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck * pdev->resource has 2 entries: io & irq 2310a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck */ 2320a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic void softingcs_pdev_release(struct device *dev) 2330a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 2340a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct platform_device *pdev = to_platform_device(dev); 2350a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck kfree(pdev); 2360a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 2370a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2380a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic __devinit int softingcs_probe(struct pcmcia_device *pcmcia) 2390a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 2400a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck int ret; 2410a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct platform_device *pdev; 2420a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck const struct softing_platform_data *pdat; 2430a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct resource *pres; 2440a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct dev { 2450a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct platform_device pdev; 2460a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck struct resource res[2]; 2470a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck } *dev; 2480a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2490a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* find matching platform_data */ 2500a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id); 2510a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (!pdat) 2520a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return -ENOTTY; 2530a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2540a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* setup pcmcia device */ 2550a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM | 2560a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; 2570a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat); 2580a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (ret) 2590a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck goto pcmcia_failed; 2600a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2610a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck ret = pcmcia_enable_device(pcmcia); 2620a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (ret < 0) 2630a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck goto pcmcia_failed; 2640a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2650a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pres = pcmcia->resource[PCMCIA_IOMEM_0]; 2660a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (!pres) { 2670a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck ret = -EBADF; 2680a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck goto pcmcia_bad; 2690a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck } 2700a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2710a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* create softing platform device */ 2720a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev = kzalloc(sizeof(*dev), GFP_KERNEL); 2730a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (!dev) { 2740a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck ret = -ENOMEM; 2750a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck goto mem_failed; 2760a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck } 2770a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev->pdev.resource = dev->res; 2780a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev->pdev.num_resources = ARRAY_SIZE(dev->res); 2790a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev->pdev.dev.release = softingcs_pdev_release; 2800a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2810a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev = &dev->pdev; 2820a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->dev.platform_data = (void *)pdat; 2830a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->dev.parent = &pcmcia->dev; 2840a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pcmcia->priv = pdev; 2850a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2860a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* platform device resources */ 2870a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->resource[0].flags = IORESOURCE_MEM; 2880a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->resource[0].start = pres->start; 2890a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->resource[0].end = pres->end; 2900a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2910a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->resource[1].flags = IORESOURCE_IRQ; 2920a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->resource[1].start = pcmcia->irq; 2930a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->resource[1].end = pdev->resource[1].start; 2940a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 2950a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* platform device setup */ 2960a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck spin_lock(&softingcs_index_lock); 2970a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->id = softingcs_index++; 2980a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck spin_unlock(&softingcs_index_lock); 2990a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pdev->name = "softing"; 3000a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev_set_name(&pdev->dev, "softingcs.%i", pdev->id); 3010a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck ret = platform_device_register(pdev); 3020a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck if (ret < 0) 3030a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck goto platform_failed; 3040a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3050a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev)); 3060a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return 0; 3070a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3080a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckplatform_failed: 3090a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck kfree(dev); 3100a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckmem_failed: 3110a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckpcmcia_bad: 3120a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckpcmcia_failed: 3130a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pcmcia_disable_device(pcmcia); 3140a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pcmcia->priv = NULL; 3150a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return ret ?: -ENODEV; 3160a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 3170a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 31825f8f54f6e178acfd503a95441b0ea05c525f751Joe Perchesstatic const struct pcmcia_device_id softingcs_ids[] = { 3190a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* softing */ 3200a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001), 3210a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002), 3220a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004), 3230a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005), 3240a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* vector, manufacturer? */ 3250a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081), 3260a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084), 3270a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085), 3280a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck /* EDIC */ 3290a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102), 3300a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105), 3310a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck PCMCIA_DEVICE_NULL, 3320a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}; 3330a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3340a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_DEVICE_TABLE(pcmcia, softingcs_ids); 3350a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3360a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic struct pcmcia_driver softingcs_driver = { 3370a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .owner = THIS_MODULE, 3380a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .name = "softingcs", 3390a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .id_table = softingcs_ids, 3400a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .probe = softingcs_probe, 3410a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck .remove = __devexit_p(softingcs_remove), 3420a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck}; 3430a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3440a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic int __init softingcs_start(void) 3450a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 3460a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck spin_lock_init(&softingcs_index_lock); 3470a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck return pcmcia_register_driver(&softingcs_driver); 3480a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 3490a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3500a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckstatic void __exit softingcs_stop(void) 3510a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck{ 3520a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck pcmcia_unregister_driver(&softingcs_driver); 3530a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck} 3540a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3550a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckmodule_init(softingcs_start); 3560a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijckmodule_exit(softingcs_stop); 3570a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck 3580a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_DESCRIPTION("softing CANcard driver" 3590a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van Dijck ", links PCMCIA card to softing driver"); 3600a0b7a5f7a043d86a95990d3227cf7e823ae52acKurt Van DijckMODULE_LICENSE("GPL v2"); 361