Author: <roberto@connexer.com>
Description: Adds a utility to support Satellite 1800 IrDA
--- /dev/null
+++ trunk/toshsat1800-irdasetup-0.2/CHANGELOG
@@ -0,0 +1 @@
+2002/04/07 Added ports 0x178 and 0x130
--- /dev/null
+++ trunk/toshsat1800-irdasetup-0.2/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+++ trunk/toshsat1800-irdasetup-0.2/Makefile
@@ -0,0 +1,2 @@
+toshsat1800-irdasetup: toshsat1800-irdasetup.c
+ gcc -g -O2 -o toshsat1800-irdasetup toshsat1800-irdasetup.c -lpci -lz
--- /dev/null
+++ trunk/toshsat1800-irdasetup-0.2/README
@@ -0,0 +1,77 @@
+toshsat1800-irdasetup
+
+Version 0.2 2002/04/07 15:42
+
+Description:
+
+IrDA configurator for laptops with ALI1533 bridge (LPC47N227 SuperIO), smc-ircc
+and not initializing BIOS (tested on Toshiba Satellite 1800-514) to be
+used with Linux kernel.
+Copyright (C) 2002, Daniele Peri <peri@csai.unipa.it>
+
+http://lancelot.csai.unipa.it/~peri/toshsat1800-irdasetup.tgz
+
+Problem:
+
+Toshiba Satellite 1800 laptops are provided with a SMCS LPC47N227 SuperIO chip which is IrDA SIR/FIR capable. The chip is connected through an ALI1533 PCI-ISA bridge. The IrDA subsystem of the SuperIO chip is supported by the smc-ircc Linux kernel module. Unfortunately the BIOS neither configurates the SuperIO chip IrDA subsystem (SIR port, FIR port, dma, irq, IrDA mode, power) nor sets the PCI-ISA bridge to decode any usable port.
+Linux kernel is thus prevented to detect the second UART making impossible to use it in SIR mode. For the same reason, the FIR mode smc-ircc is able to detect the SuperIO chip but, once found the IrDA subsystem unconfigured, fails to install.
+
+Solution:
+
+toshsat1800-irdasetup sets SIR and FIR ioport addresses, DMA and IRQ of the SuperIO chip IrDA subsystem then powers on the second UART. It also configures the PCI-ISA bridge to decode SIR and FIR ports. All this configuration work should be rather done into the kernel but it was more practical and safe to make a small testing tool of it. It can be probably extended to include configuration kludges for other similar SuperIO and ISA bridge combination.
+Testing was carried on a Toshiba Satellite 1800-514 with Linux kernel 2.4.17.
+I hope this work could be helpful, it was quite funny to do it however.
+
+Compilation (Requires pci-utils):
+
+ $ cd toshsat1800-irdasetup/
+ $ make
+
+Usage:
+
+Run it as root:
+ $ ./toshsat1800-irdasetup
+
+then you can install the smc-ircc module:
+ $ modprobe smc-ircc
+
+I've noticed that the smc-ircc needs parameters ircc_sir and ircc_fir to be specified. So you'd probably add:
+
+ options smc-ircc ircc_dma=3 ircc_irq=7 ircc_cfg=0x2e ircc_sir=0x2e8 ircc_fir=0x2f8
+
+to /etc/modules.conf
+
+You may also want to add a line like:
+
+ pre-install smc-ircc /usr/local/sbin/toshsat1800-smcinit
+
+to /etc/modules.conf in order to obtain full automatic IrDA setup.
+You'll need to execute:
+
+ $ depmod -a
+
+after modifying /etc/modules.conf to make changes effective.
+
+Default values works for Toshiba Satellite 1800 though any configuration value can be changed through options. So far I've discovered how to enable decoding of the following usable ports: 0x2e8, 0x2f8, 0x130, 0x178.
+The list of all options is obtaineable through:
+
+ $ toshsat1800-irdasetup --help
+
+
+Appendix:
+
+Ericsson T39m. Setting up an Ircomm link with this phone requires to explicitly reduce the maximum speed to 115200:
+
+ $ echo 115200 > /proc/sys/net/irda/max_baud_rate
+
+Disclaimer:
+This software is experimental. Use it at your own risk.
+
+Credits:
+
+* SMSC for the downloadable datasheets
+* Paul Hampson for its Linux IrDA mailing list messages.
+
+To do:
+
+* Add more ALI1533 usable ports
--- /dev/null
+++ trunk/toshsat1800-irdasetup-0.2/toshsat1800-irdasetup.c
@@ -0,0 +1,742 @@
+/*
+ * toshsat1800-irdasetup.c
+ *
+ * Version 0.2 2002/04/07 15:42
+ *
+ * toshsat1800-irdasetup
+ *
+ * IrDA configurator for laptops with ALI1533 bridge (47n227 SuperIO),
+ * smc-ircc and not initializing BIOS (tested on Toshiba Satellite 1800-514)
+ * to be used with Linux kernel.
+ * Copyright (C) 2002, Daniele Peri <peri@csai.unipa.it>
+ *
+ * http://lancelot.csai.unipa.it/~peri/toshsat1800-irdasetup.tgz
+ *
+ *
+ * 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <sys/io.h>
+#include <errno.h>
+#include <getopt.h>
+#include <pci/pci.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * Debug Macros
+ */
+
+#undef DEBUG_ON
+
+#ifdef DEBUG_ON
+static int _debug= 0;
+#define DEBUG_LEVEL(level) _debug=level
+#define DEBUG(label) if(_debug){fprintf(stderr, "%s: %s\n", PROGNAME, label);}
+#define DEBUG_VAL(label, val) if(_debug){fprintf(stderr, "%s: %s: 0x%x\n", PROGNAME, label, val);}
+#define DEBUG_STRING(label, val) if(_debug){fprintf(stderr, "%s: %s: %s\n", PROGNAME, label, val);}
+#endif
+#ifndef DEBUG_ON
+#define DEBUG_LEVEL(level)
+#define DEBUG(label)
+#define DEBUG_VAL(label, val)
+#define DEBUG_STRING(label, val)
+#endif
+
+#define ERROR(label) fprintf(stderr, "%s: %s: %s\n", PROGNAME, label, strerror(errno));
+
+#define PROGNAME "toshsat1800-irdasetup"
+#define VERSION "0.2 2002/04/07 15:42"
+#define AUTHOR "Daniele Peri"
+#define AUTHOR_EMAIL "<peri@csai.unipa.it>"
+
+/*
+ * ALI 1533 bitmapped decode addresses
+ */
+struct port_decoding_access_info
+{
+ int port;
+ byte reg;
+ byte or_mask;
+};
+
+struct port_decoding_access_info ali1533_ports[]=
+{
+ {0x130, 0xb0, 0x80}, /* this sounds confusing: */
+ {0x178, 0xb0, 0x80}, /* both ports are decoded */
+
+ {0x3f8, 0xb4, 0x80},
+ {0x2f8, 0xb4, 0x30}, /* bit 4 enables decoding, bit 5 enables something unknown it can't stand without...*/
+ {0x2e8, 0xb4, 0x08},
+ /* the followings are all the active bits in the default bitmap of
+ Satellite1800-514:
+
+ {0x3f8, 0xb4, 0x80},
+ {0x???, 0xb6, 0x80},
+ {0x???, 0xb6, 0x80},
+ {0x???, 0xb7, 0x40},
+ {0x???, 0xb7, 0x20},
+ {0x???, 0xb7, 0x10},
+ {0x???, 0xb7, 0x02},
+ {0x???, 0xb8, 0x80},
+ {0x???, 0xb8, 0x40},
+ {0x???, 0xb8, 0x02},
+ {0x???, 0xb9, 0x04},
+ {0x???, 0xb9, 0x02},
+
+ According to Paul Hampson decoded ISA ports are thus:
+ 2e, 2f, 62, 66, 60, 64, 378-37f, 778-77f, 2f0-2f5, 3f7, 3f8-3ff
+
+ Unfortunately I don't have any other information about the ALI1533.
+ */
+ {0, 0, 0}
+};
+
+/* SMC-IRCC
+ *
+ *
+ */
+
+/* Chip specific config function(s) */
+static int
+configure_47N227_smc_ircc(int revision, int cfgbase, int sirbase, int firbase, int dma, int irq);
+
+struct smc_chip_model
+{
+ char *name;
+ byte version_id;
+ int (*config_function)(int revision, int cfgbase, int sirbase, int firbase, int dma, int irq);
+};
+
+static struct smc_chip_model smc_chips[]=
+{
+ {"LPC47N227", 0x5a, configure_47N227_smc_ircc },
+ {NULL, 0, NULL}
+};
+
+/*
+ * LPC47N227
+ */
+
+#define LPC47N227_CFGACCESSKEY 0x55
+#define LPC47N227_CFGEXITKEY 0xaa
+
+/* Register 0x00 */
+#define LPC47N227_FDCPOWERVALIDCONF_REG 0x00
+#define LPC47N227_FDCPOWER_MASK 0x08
+#define LPC47N227_VALID_MASK 0x80
+
+/* Register 0x02 */
+#define LPC47N227_UART12POWER_REG 0x02
+#define LPC47N227_UART1POWERDOWN_MASK 0x08
+#define LPC47N227_UART2POWERDOWN_MASK 0x80
+
+/* Register 0x07 */
+#define LPC47N227_APMBOOTDRIVE_REG 0x07
+#define LPC47N227_PARPORT2AUTOPWRDOWN_MASK 0x10 /* auto power down on if set */
+#define LPC47N227_UART2AUTOPWRDOWN_MASK 0x20 /* auto power down on if set */
+#define LPC47N227_UART1AUTOPWRDOWN_MASK 0x40 /* auto power down on if set */
+
+/* Register 0x0c */
+#define LPC47N227_UARTMODE0C_REG 0x0c
+#define LPC47N227_UART2MODE_MASK 0x38
+#define LPC47N227_UART2MODE_VAL_COM 0x00
+#define LPC47N227_UART2MODE_VAL_IRDA 0x08
+#define LPC47N227_UART2MODE_VAL_ASKIR 0x10
+
+/* Register 0x0d */
+#define LPC47N227_DEVICEID_REG 0x0d
+#define LPC47N227_DEVICEID_DEFVAL 0x5a
+
+/* Register 0x0e */
+#define LPC47N227_REVISIONID_REG 0x0e
+
+/* Register 0x25 */
+#define LPC47N227_UART2BASEADDR_REG 0x25
+
+/* Register 0x28 */
+#define LPC47N227_UARTIRQSELECT_REG 0x28
+#define LPC47N227_UART2IRQSELECT_MASK 0x0f
+#define LPC47N227_UART1IRQSELECT_MASK 0xf0
+#define LPC47N227_UARTIRQSELECT_VAL_NONE 0x00
+
+/* Register 0x2b */
+#define LPC47N227_FIRBASEADDR_REG 0x2b
+
+/* Register 0x2c */
+#define LPC47N227_FIRDMASELECT_REG 0x2c
+#define LPC47N227_FIRDMASELECT_MASK 0x0f
+#define LPC47N227_FIRDMASELECT_VAL_DMA1 0x01 /* 47n227 has three dma channels */
+#define LPC47N227_FIRDMASELECT_VAL_DMA2 0x02
+#define LPC47N227_FIRDMASELECT_VAL_DMA3 0x03
+#define LPC47N227_FIRDMASELECT_VAL_NONE 0x0f
+
+
+/*
+ * Defaults values for Toshiba Satellite 1800-514
+ */
+#define DEF_CFGBASE 0x2e
+#define DEF_SIRBASE 0x2e8
+#define DEF_FIRBASE 0x2f8
+#define DEF_DMA 0x03
+#define DEF_IRQ 0x07
+#define DEF_ISABRIDGE_VENDOR_ID 0x10b9
+#define DEF_ISABRIDGE_DEVICE_ID 0x1533
+
+/*
+ * Actions
+ */
+#define ACTION_CONFIG_ALI1533_PORTS_DECODING 1
+#define ACTION_INIT_SMC_IRCC 2
+#define ACTION_PRINT_ALI1533_CONFIGURATION 4
+#define DEF_ACTIONS ACTION_CONFIG_ALI1533_PORTS_DECODING | ACTION_INIT_SMC_IRCC
+
+struct option options[]= {
+ {"skip-decoding-cfg", no_argument, NULL, 'a'},
+ {"skip-smc-ircc-cfg", no_argument, NULL, 'b'},
+ {"vendor", required_argument, NULL, 'v'},
+ {"device", required_argument, NULL, 'x'},
+ {"cfgbase", required_argument, NULL, 'c'},
+ {"sirbase", required_argument, NULL, 's'},
+ {"firbase", required_argument, NULL, 'f'},
+ {"dma", required_argument, NULL, 'm'},
+ {"irq", required_argument, NULL, 'i'},
+ {"print", no_argument, NULL, 'p'},
+ {"help", no_argument, NULL, 'h'},
+ #ifdef DEBUG_ON
+ {"debug", no_argument, NULL, 'd'},
+ #endif
+ {NULL, 0, NULL, 0}
+};
+
+static char *options_explications[]= {
+ "\tskip ISA bridge decoding configuration",
+ "\tskip SMC-IRCC configuration",
+ "\tlook for the specified ISA bridge PCI vendor id",
+ "\tlook for the specified ISA bridge PCI device id",
+ "\tset SMC-IRCC IO cfgbase address",
+ "\tset SMC-IRCC IO sirbase address",
+ "\tset SMC-IRCC IO firbase address",
+ "\t\tset SMC-IRCC DMA channel",
+ "\t\tset SMC-IRCC IRQ",
+ "\t\tprint ISA bridge configuration",
+ "\t\tshow this help",
+ #ifdef DEBUG_ON
+ NULL,
+ #endif
+ NULL
+};
+
+
+#ifdef DEBUG_ON
+static char *short_options= "abpv:x:c:s:f:m:i:dh";
+#endif
+#ifndef DEBUG_ON
+static char *short_options= "abpv:x:c:s:f:m:i:h";
+#endif
+
+/* ALI 1533 */
+
+static int
+find_ali1533_port_access_info(long port, struct port_decoding_access_info *info)
+{
+ struct port_decoding_access_info *p;
+ int i;
+
+ p= &ali1533_ports[0];
+ i=0;
+ while(p->port!=0)
+ {
+ DEBUG_VAL("port", p->port);
+ if(p->port==port)
+ {
+ memcpy(info, p, sizeof(struct port_decoding_access_info));
+ return 1;
+ }
+ i++;
+ p= &ali1533_ports[i];
+ }
+ return 0;
+}
+
+static int
+print_ali1533_port_status(struct pci_dev *dev)
+{
+ struct port_decoding_access_info *p;
+ byte onebyte;
+ int i;
+
+ DEBUG("printing port status");
+ p= &ali1533_ports[0];
+ i=0;
+ puts("ALi 1533 Decoding status:");
+ while(p->port!=0)
+ {
+ DEBUG_VAL("port", p->port);
+ onebyte= pci_read_byte(dev, p->reg);
+ printf("port 0x%x %s\n", p->port, (onebyte & p->or_mask ? "enabled" : "disabled"));
+ i++;
+ p= &ali1533_ports[i];
+ }
+ return 0;
+}
+
+/* Sets ALi1533 port decoding mode and
+ * returns previous port decoding mode
+ * (0=disabled, 1=enabled, -1 port unknown)
+ */
+
+static int
+set_ali1533_port(struct pci_dev *dev, int port, int decode)
+{
+ struct port_decoding_access_info info;
+ byte previousval, onebyte, and_mask;
+ int retval;
+
+ DEBUG_VAL("looking for port", port);
+ retval= find_ali1533_port_access_info(port, &info);
+ if(retval)
+ {
+ previousval= pci_read_byte(dev, info.reg);
+ DEBUG_VAL("current register value", previousval);
+ and_mask= ~info.or_mask;
+ DEBUG_VAL("and with mask", and_mask);
+ onebyte= previousval & and_mask;
+ if(decode)
+ {
+ DEBUG_VAL("or with mask", info.or_mask);
+ onebyte |= info.or_mask;
+ }
+ DEBUG_VAL("writing value", onebyte);
+ pci_write_byte(dev, info.reg, onebyte);
+ return (previousval & info.or_mask) ? 1 : 0;
+ }
+ else DEBUG_VAL("unknown port", port);
+ return -1;
+}
+
+
+/* PCI */
+
+static struct pci_dev*
+find_pci_device(struct pci_access *access, struct pci_filter *filter)
+{
+ struct pci_dev *dev;
+
+ DEBUG("scanning PCI busses");
+ pci_scan_bus(access);
+
+ DEBUG("looking for PCI device");
+ for(dev=access->devices; dev; dev=dev->next)
+ {
+ if(pci_filter_match(filter, dev))
+ {
+ DEBUG("device found");
+ DEBUG_VAL("bus", dev->bus);
+ DEBUG_VAL("dev", dev->dev);
+ DEBUG_VAL("func", dev->func);
+ return dev;
+ }
+ }
+ return NULL;
+}
+
+/* Configure ali1533 PCI-ISA bridge to decode
+ * SMC-IRCC ports
+ */
+static int
+configure_ali1533_smc_ports_decoding(int vendor_id, int device_id, int cfgbase, int firbase, int sirbase, int print)
+{
+ struct pci_access *access;
+ struct pci_dev *dev= NULL;
+ struct pci_filter filter;
+ int ports[2], port_previous_mode, i;
+ char *val;
+ byte byte;
+
+ access = pci_alloc();
+ if(access==NULL)
+ {
+ DEBUG("impossible to obtain PCI access");
+ return 0;
+ }
+ DEBUG("initializing filter");
+ pci_filter_init(access, &filter);
+ filter.vendor= vendor_id;
+ filter.device= device_id;
+
+ pci_init(access);
+
+ dev= find_pci_device(access, &filter);
+ if(dev)
+ {
+ if(print)
+ {
+ print_ali1533_port_status(dev);
+ }
+ else
+ {
+
+ syslog(
+ LOG_NOTICE,
+ "PCI device 0x%x:0x%x found at %02x:%02x:%02x. Configuring:",
+ vendor_id,
+ device_id,
+ dev->bus,
+ dev->dev,
+ dev->func
+ );
+ ports[0]= sirbase;
+ ports[1]= firbase;
+ for(i=0; i<2; i++)
+ {
+ port_previous_mode= set_ali1533_port(dev, ports[i], 1);
+ if(port_previous_mode==1)
+ {
+ syslog(
+ LOG_ERR,
+ "port 0x%x was already enabled",
+ ports[i]
+ );
+ }
+ else
+ {
+ syslog(
+ LOG_NOTICE,
+ "enabled decoding of port 0x%x",
+ ports[i]
+ );
+ }
+ }
+ }
+ }
+ if(dev!=NULL)
+ {
+ syslog(
+ LOG_NOTICE,
+ "PCI device 0x%x:0x%x. Configuration ended",
+ vendor_id,
+ device_id
+ );
+
+ }
+ else
+ {
+ syslog(LOG_ERR, "PCI device 0x%x:0x%x not found", vendor_id, device_id);
+ }
+ pci_cleanup(access);
+ return dev!=NULL;
+}
+
+/* SMC IRCC
+ *
+ *
+ */
+
+/* Configure 47N227 SuperIO IrDA subsystem
+ *
+ */
+
+static int
+configure_47N227_smc_ircc(int revision, int cfgbase, int sirbase, int firbase, int dma, int irq)
+{
+ byte onebyte;
+ int retval;
+
+ DEBUG_VAL("trying to init SMC with cfgbase", cfgbase);
+ retval= ioperm(cfgbase, 2, 1);
+ if(retval== -1)
+ {
+ syslog(
+ LOG_ERR,
+ "failed to obtain ioperm for cfgbase %m"
+ );
+
+ ERROR("failed to obtain ioperm for cfgbase");
+ return 0;
+ }
+
+
+ outb(LPC47N227_CFGACCESSKEY, cfgbase);
+ /*
+ outb(LPC47N227_DEVICEID_REG, cfgbase);
+ if (inb(cfgbase+1) == LPC47N227_DEVICEID_DEFVAL)
+ {
+ */
+ /*syslog(LOG_NOTICE, "LPC47N227 present. Configuring:");*/
+
+ /*SIR Base*/
+ DEBUG_VAL("setting sirbase to", sirbase);
+ outb(LPC47N227_UART2BASEADDR_REG, cfgbase);
+ onebyte= sirbase>>2;
+ outb(onebyte, cfgbase+1);
+
+ /* FIR Base */
+ DEBUG_VAL("setting firbase to", firbase);
+ outb(LPC47N227_FIRBASEADDR_REG, cfgbase);
+ onebyte= firbase>>3;
+ outb(onebyte, cfgbase+1);
+
+ /* DMA */
+ DEBUG_VAL("setting dma to", dma);
+ outb(LPC47N227_FIRDMASELECT_REG, cfgbase);
+ outb(dma&LPC47N227_FIRDMASELECT_MASK, cfgbase+1);
+
+ /* IRQ */
+ DEBUG_VAL("setting irq to", irq);
+ outb(LPC47N227_UARTIRQSELECT_REG, cfgbase);
+ onebyte = inb(cfgbase+1);
+ onebyte &= LPC47N227_UART1IRQSELECT_MASK;
+ onebyte |= (irq & LPC47N227_UART2IRQSELECT_MASK);
+ outb(onebyte, cfgbase+1);
+
+ syslog(
+ LOG_NOTICE,
+ "set sirbase=0x%x, firbase=0x%x, dma=%d, irq=%d",
+ sirbase,
+ firbase,
+ dma,
+ irq
+ );
+
+ DEBUG("setting other registers");
+
+ /* Set UART2 mode to IrDA */
+ outb(LPC47N227_UARTMODE0C_REG, cfgbase);
+ onebyte = inb(cfgbase+1);
+ onebyte &= ~LPC47N227_UART2MODE_MASK | LPC47N227_UART2MODE_VAL_IRDA;
+ outb(onebyte, cfgbase+1);
+
+ /* Set UART2 AUTO POWER DOWN */
+ outb(LPC47N227_APMBOOTDRIVE_REG, cfgbase);
+ onebyte = inb(cfgbase+1);
+ outb(onebyte | LPC47N227_UART2AUTOPWRDOWN_MASK, cfgbase+1);
+
+ /* Set UART2 POWER ON */
+ outb(LPC47N227_UART12POWER_REG, cfgbase);
+ onebyte = inb(cfgbase+1);
+ outb(onebyte | LPC47N227_UART2POWERDOWN_MASK, cfgbase+1);
+
+ syslog(
+ LOG_NOTICE,
+ "set UART 2 IR mode to IrDA, auto powerdown on and powered up"
+ );
+
+ /* Validate configuration */
+ outb(LPC47N227_FDCPOWERVALIDCONF_REG, cfgbase);
+ onebyte = inb(cfgbase + 1);
+ outb(onebyte | LPC47N227_VALID_MASK, cfgbase + 1);
+
+ outb(LPC47N227_CFGEXITKEY, cfgbase);
+ DEBUG("configuration ended");
+ return 1;
+}
+
+static struct smc_chip_model *
+find_smc_chip_model(struct smc_chip_model *chips, int version_id)
+{
+ int i;
+ for(i=0; smc_chips[i].name!=NULL; i++)
+ {
+ if(smc_chips[i].version_id=version_id) return &smc_chips[i];
+ }
+ return NULL;
+}
+
+static int
+configure_smc_ircc(int cfgbase, int sirbase, int firbase, int dma, int irq)
+{
+ byte version_id, revision_id, onebyte;
+ struct smc_chip_model *chip_model;
+ void *config_function;
+ int retval;
+
+ DEBUG_VAL("trying to init SMC with cfgbase", cfgbase);
+ retval= ioperm(cfgbase, 2, 1);
+ if(retval== -1)
+ {
+ syslog(
+ LOG_ERR,
+ "failed to obtain ioperm for cfgbase %m"
+ );
+
+ ERROR("failed to obtain ioperm for cfgbase");
+ return 0;
+ }
+
+ outb(LPC47N227_CFGACCESSKEY, cfgbase);
+ outb(LPC47N227_DEVICEID_REG, cfgbase);
+ version_id= inb(cfgbase+1);
+ outb(LPC47N227_REVISIONID_REG, cfgbase);
+ revision_id= inb(cfgbase+1);
+ outb(LPC47N227_CFGEXITKEY, cfgbase);
+
+ chip_model= find_smc_chip_model(smc_chips, version_id);
+ if(chip_model!=NULL)
+ {
+ syslog(LOG_NOTICE, "%s chip (ver 0x%x, rev 0x%x) found. Configuring:", chip_model->name, version_id, revision_id);
+ retval= (*(chip_model->config_function))(revision_id, cfgbase, sirbase, firbase, dma, irq);
+ syslog(LOG_NOTICE, "%s chip (ver 0x%x, rev 0x%x) configuration %ssuccessfully ended", chip_model->name, version_id, revision_id, (retval ? "" : "un"));
+ return 1;
+ }
+ else
+ {
+ syslog(LOG_ERR, "Unknown chip version 0x%", version_id);
+ return 0;
+ }
+}
+
+static void
+print_usage(struct option *options_array, char **options_explications_array)
+{
+ struct option *option;
+ char *option_explication=NULL;
+ int i;
+
+ printf("%s %s %s\nUsage: %s [options]\nOptions:\n", PROGNAME, VERSION, AUTHOR, PROGNAME);
+ i=0;
+ option= &options_array[0];
+ option_explication= options_explications_array[0];
+ while(option->name!=NULL)
+ {
+ printf("-%c, --%s%s", option->val, option->name, (option->has_arg ? "=VALUE" : ""));
+ if(options_explications_array[i] != NULL) printf("%s\n", options_explications_array[i]);
+ else puts("\n");
+ i++;
+ option=&options[i];
+ option_explication= options_explications_array[i];
+ }
+ printf("Report suggestions and bugs to: %s\n", AUTHOR " "AUTHOR_EMAIL);
+}
+
+int
+main(int argc, char **argv)
+{
+ int uid;
+ int cfgbase= DEF_CFGBASE;
+ int sirbase= DEF_SIRBASE;
+ int firbase= DEF_FIRBASE;
+ int dma= DEF_DMA;
+ int irq= DEF_IRQ;
+ int isabridge_vendor_id= DEF_ISABRIDGE_VENDOR_ID;
+ int isabridge_device_id= DEF_ISABRIDGE_DEVICE_ID;
+ int actions= DEF_ACTIONS;
+ int retval, opt;
+
+ if(getuid()!=0)
+ {
+ fprintf(stderr, "%s can only be used by root\n", PROGNAME);
+ exit(1);
+ }
+
+ while ((opt= getopt_long(argc, argv, short_options, options, NULL)) != -1)
+ {
+ switch(opt)
+ {
+ case 'a' :
+ {
+ actions &= ~ACTION_CONFIG_ALI1533_PORTS_DECODING;
+ break;
+ }
+ case 'b' :
+ {
+ actions &= ~ACTION_INIT_SMC_IRCC;
+ break;
+ }
+ case 'p' :
+ {
+ actions |= ACTION_PRINT_ALI1533_CONFIGURATION;
+ break;
+ }
+ case 'v' :
+ {
+ isabridge_vendor_id=strtoul(optarg, NULL, 0);
+ break;
+ }
+ case 'x' :
+ {
+ isabridge_device_id=strtoul(optarg, NULL, 0);
+ break;
+ }
+ case 'c' :
+ {
+ cfgbase=strtoul(optarg, NULL, 0);
+ break;
+ }
+ case 's' :
+ {
+ sirbase=strtoul(optarg, NULL, 0);
+ break;
+ }
+ case 'f' :
+ {
+ firbase=strtoul(optarg, NULL, 0);
+ break;
+ }
+ case 'm' :
+ {
+ dma=strtoul(optarg, NULL, 0);
+ break;
+ }
+ case 'i' :
+ {
+ irq=strtoul(optarg, NULL, 0);
+ break;
+ }
+ #ifdef DEBUG_ON
+ case 'd' :
+ {
+ DEBUG_LEVEL(1);
+ break;
+ }
+ #endif
+ case 'h' :
+ {
+ print_usage(options, options_explications);
+ exit(0);
+ break;
+ }
+
+ default :
+ break;
+ }
+ }
+
+ if(actions&(ACTION_INIT_SMC_IRCC | ACTION_CONFIG_ALI1533_PORTS_DECODING))
+ {
+ syslog(LOG_INFO, "%s %s %s", PROGNAME, VERSION, AUTHOR);
+ }
+
+ if(actions&ACTION_INIT_SMC_IRCC)
+ {
+ retval= configure_smc_ircc(cfgbase, sirbase, firbase, dma, irq);
+ }
+
+ if(actions&ACTION_CONFIG_ALI1533_PORTS_DECODING && retval)
+ {
+ retval= configure_ali1533_smc_ports_decoding(
+ isabridge_vendor_id,
+ isabridge_device_id,
+ cfgbase,
+ firbase,
+ sirbase,
+ actions&ACTION_PRINT_ALI1533_CONFIGURATION
+ );
+ }
+
+ exit(!retval);
+}