/* * Written by Oron Peled * Copyright (C) 2004-2006, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "xproto.h" #include "slic.h" static const char rcsid[] = "$Id$"; #ifdef __KERNEL__ #include extern int print_dbg; #include "zap_debug.h" DEF_PARM(charp,initialize_registers, "/usr/share/zaptel/initialize_registers", "The script to initialize detected cards slics"); #else #include #endif int slic_cmd_direct_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data) { struct slic_reg_d *p = (struct slic_reg_d *)&sc->content; sc->lines = lines; sc->bytes = sizeof(struct slic_reg_d); SLIC_REG_INIT(p, 0, reg, data); return sizeof(xpp_line_t) + 1 + sc->bytes; } int slic_cmd_direct_read(slic_cmd_t *sc, xpp_line_t lines, byte reg) { struct slic_reg_d *p = (struct slic_reg_d *)&sc->content; sc->lines = lines; sc->bytes = sizeof(struct slic_reg_d); SLIC_REG_INIT(p, 1, reg, 0); return sizeof(xpp_line_t) + 1 + sc->bytes; } int slic_cmd_indirect_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data_low, byte data_high) { struct slic_reg_iw *p = (struct slic_reg_iw *)&sc->content; sc->lines = lines; sc->bytes = sizeof(struct slic_reg_iw); SLIC_REG_INIT(&p->iw_data_low, 0, 0x1C, data_low); SLIC_REG_INIT(&p->iw_data_high, 0, 0x1D, data_high); SLIC_REG_INIT(&p->iw_reg, 0, 0x1E, reg); return sizeof(xpp_line_t) + 1 + sc->bytes; } int slic_cmd_indirect_read(slic_cmd_t *sc, xpp_line_t lines, byte reg) { struct slic_reg_ir *p = (struct slic_reg_ir *)&sc->content; sc->lines = lines; sc->bytes = sizeof(struct slic_reg_ir); SLIC_REG_INIT(&p->ir_reg, 0, 0x1E, reg); return sizeof(xpp_line_t) + 1 + sc->bytes; } void dump_slic_cmd(const char msg[], slic_cmd_t *sc) { int i; struct slic_reg_d *sr; int last_data_low = -1; int last_data_high = -1; sr = (struct slic_reg_d *)&sc->content; if(sc->bytes > sizeof(sc->content)) { NOTICE("%s: Bug: sc->bytes = %d\n", __FUNCTION__, sc->bytes); return; } if(sc->bytes % 2) { NOTICE("%s: Bug: ODD sc->bytes = %d\n", __FUNCTION__, sc->bytes); return; } for(i = 0; i < sc->bytes/2; i++, sr++) { if(sr->reg_num == 0x1C) { last_data_low = sr->reg_data; continue; } if(sr->reg_num == 0x1D) { last_data_high = sr->reg_data; continue; } if(sr->reg_num == 0x1E) { if(last_data_low == -1 && last_data_high == -1) // Indirect Read DBG("%s: LINES=0x%08X bytes=%d INDIRECT READ: register=0x%02X\n", msg, sc->lines, sc->bytes, sr->reg_data); else if(last_data_low == -1 || last_data_high == -1) { NOTICE("%s: BUG: PARTIAL INDIRECT: register=%d last_data_low=0x%X last_data_high=0x%X\n", msg, sr->reg_data, last_data_low, last_data_high); } else DBG("%s: LINES=0x%08X bytes=%d INDIRECT WRITE: register=%d data_low=0x%02x data_high=0x%02X\n", msg, sc->lines, sc->bytes, sr->reg_data, (byte)last_data_low, (byte)last_data_high); last_data_low = last_data_high = -1; } else { DBG("%s: LINES=0x%08X bytes=%d DIRECT %s: register=%d data=0x%02X\n", msg, sc->lines, sc->bytes, (sr->read) ? "READ" : "WRITE", sr->reg_num, sr->reg_data); } } } #ifdef __KERNEL__ #define MAX_ENV_STR 20 int run_initialize_registers(xpd_t *xpd) { int ret; xbus_t *xbus; char busstr[MAX_ENV_STR]; char xpdstr[MAX_ENV_STR]; char typestr[MAX_ENV_STR]; char revstr[MAX_ENV_STR]; char *argv[] = { initialize_registers, NULL }; char *envp[] = { busstr, xpdstr, typestr, revstr, NULL }; BUG_ON(!xpd); xbus = xpd->xbus; if(!initialize_registers || !initialize_registers[0]) { NOTICE("%s/%s: No runtime register initialization\n", xbus->busname, xpd->xpdname); return 0; } DBG("%s/%s: running: '%s'\n", xbus->busname, xpd->xpdname, initialize_registers); snprintf(busstr, MAX_ENV_STR, "XPD_BUS=%s", xbus->busname); snprintf(xpdstr, MAX_ENV_STR, "XPD_NAME=%s", xpd->xpdname); snprintf(typestr, MAX_ENV_STR, "XPD_TYPE=%d", xpd->type); snprintf(revstr, MAX_ENV_STR, "XPD_REVISION=%d", xpd->revision); DBG("%s/%s: type=%d revision=%d\n", xbus->busname, xpd->xpdname, xpd->type, xpd->revision); ret = call_usermodehelper(initialize_registers, argv, envp, 1); if(ret != 0) { ERR("%s/%s: Failed running '%s' (errno %d, sig=%d)\n", xbus->busname, xpd->xpdname, initialize_registers, ((unsigned)ret >> 8) & 0xFF, ret & 0xFF); ret = -EFAULT; } return ret; } EXPORT_SYMBOL(slic_cmd_direct_write); EXPORT_SYMBOL(slic_cmd_direct_read); EXPORT_SYMBOL(slic_cmd_indirect_write); EXPORT_SYMBOL(slic_cmd_indirect_read); EXPORT_SYMBOL(dump_slic_cmd); #endif