]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i4b/layer1/i4b_sws.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / sys / i4b / layer1 / i4b_sws.c
1 /*
2  *   Copyright (c) 1998 German Tischler. All rights reserved.
3  *
4  *   Redistribution and use in source and binary forms, with or without
5  *   modification, are permitted provided that the following conditions
6  *   are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  *   2. Redistributions in binary form must reproduce the above copyright
11  *      notice, this list of conditions and the following disclaimer in the
12  *      documentation and/or other materials provided with the distribution.
13  *   3. Neither the name of the author nor the names of any co-contributors
14  *      may be used to endorse or promote products derived from this software
15  *      without specific prior written permission.
16  *   4. Altered versions must be plainly marked as such, and must not be
17  *      misrepresented as being the original software and/or documentation.
18  *   
19  *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  *   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  *   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  *   SUCH DAMAGE.
30  *
31  *---------------------------------------------------------------------------
32  *
33  * Card format:
34  * 
35  * iobase + 0 : reset on  (0x03)
36  * iobase + 1 : reset off (0x0)
37  * iobase + 2 : isac read/write
38  * iobase + 3 : hscx read/write ( offset 0-0x3f    hscx0 , 
39  *                                offset 0x40-0x7f hscx1 )
40  * iobase + 4 : offset for indirect adressing
41  *
42  *---------------------------------------------------------------------------
43  *
44  *      isic - I4B Siemens ISDN Chipset Driver for SWS cards
45  *      ====================================================
46  *
47  *      $Id: i4b_sws.c,v 1.2 1999/12/13 21:25:26 hm Exp $
48  *
49  * $FreeBSD$
50  *
51  *      last edit-date: [Mon Dec 13 22:02:39 1999]
52  *
53  *---------------------------------------------------------------------------*/
54
55 #include "isic.h"
56 #include "opt_i4b.h"
57
58 #if defined (SEDLBAUER) && NISIC > 0
59
60 #define SWS_RESON  0 /* reset on                 */
61 #define SWS_RESOFF 1 /* reset off                */
62 #define SWS_ISAC   2 /* ISAC                     */
63 #define SWS_HSCX0  3 /* HSCX0                    */
64 #define SWS_RW     4 /* indirect access register */
65 #define SWS_HSCX1  5 /* this is for fakeing that we mean hscx1, though */
66                      /* access is done through hscx0                   */
67
68 #define SWS_REGS   8 /* we use an area of 8 bytes for io */
69
70 #include <sys/param.h>
71 #include <sys/ioccom.h>
72 #include <sys/kernel.h>
73 #include <sys/systm.h>
74 #include <sys/mbuf.h>
75 #include <sys/socket.h>
76
77 #include <machine/clock.h>
78
79 #include <net/if.h>
80
81 #include <machine/i4b_debug.h>
82 #include <machine/i4b_ioctl.h>
83
84 #include <i4b/layer1/i4b_l1.h>
85 #include <i4b/layer1/i4b_isac.h>
86 #include <i4b/layer1/i4b_hscx.h>
87
88 #include <i4b/include/i4b_global.h>
89 #include <i4b/include/i4b_l1l2.h>
90 #include <i4b/include/i4b_mbuf.h>
91
92 /*---------------------------------------------------------------------------*
93  *      SWS P&P ISAC get fifo routine
94  *---------------------------------------------------------------------------*/
95 static void
96 sws_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size) {
97         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
98         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
99
100         switch ( what ) {
101                 case ISIC_WHAT_ISAC:
102                         bus_space_write_1(t,h,SWS_RW,0x0);
103                         bus_space_read_multi_1(t,h,SWS_ISAC,buf,size);
104                         break;
105                 case ISIC_WHAT_HSCXA:
106                         bus_space_write_1(t,h,SWS_RW,0x0);
107                         bus_space_read_multi_1(t,h,SWS_HSCX0,buf,size);
108                         break;
109                 case ISIC_WHAT_HSCXB:
110                         bus_space_write_1(t,h,SWS_RW,0x0+0x40);
111                         bus_space_read_multi_1(t,h,SWS_HSCX0,buf,size);
112                         break;
113         }
114 }
115
116 static void
117 sws_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size) {
118         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
119         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
120
121         switch ( what ) {
122                 case ISIC_WHAT_ISAC:
123                         bus_space_write_1(t,h,SWS_RW,0x0);
124                         bus_space_write_multi_1(t,h,SWS_ISAC,buf,size);
125                         break;
126                 case ISIC_WHAT_HSCXA:
127                         bus_space_write_1(t,h,SWS_RW,0x0);
128                         bus_space_write_multi_1(t,h,SWS_HSCX0,buf,size);
129                         break;
130                 case ISIC_WHAT_HSCXB:
131                         bus_space_write_1(t,h,SWS_RW,0x0+0x40);
132                         bus_space_write_multi_1(t,h,SWS_HSCX0,buf,size);
133                         break;
134         }
135 }
136
137 static void
138 sws_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data) {
139         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
140         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
141
142         switch ( what ) {
143                 case ISIC_WHAT_ISAC:
144                         bus_space_write_1(t,h,SWS_RW,reg);
145                         bus_space_write_1(t,h,SWS_ISAC,data);
146                         break;
147                 case ISIC_WHAT_HSCXA:
148                         bus_space_write_1(t,h,SWS_RW,reg);
149                         bus_space_write_1(t,h,SWS_HSCX0,data);
150                         break;
151                 case ISIC_WHAT_HSCXB:
152                         bus_space_write_1(t,h,SWS_RW,reg+0x40);
153                         bus_space_write_1(t,h,SWS_HSCX0,data);
154                         break;
155         }
156 }
157
158 static u_char
159 sws_read_reg (struct l1_softc *sc,int what,bus_size_t reg) {
160         bus_space_tag_t    t = rman_get_bustag(sc->sc_resources.io_base[0]);
161         bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
162
163         switch ( what ) {
164                 case ISIC_WHAT_ISAC:
165                         bus_space_write_1(t,h,SWS_RW,reg);
166                         return bus_space_read_1(t,h,SWS_ISAC);
167                 case ISIC_WHAT_HSCXA:
168                         bus_space_write_1(t,h,SWS_RW,reg);
169                         return bus_space_read_1(t,h,SWS_HSCX0);
170                 case ISIC_WHAT_HSCXB:
171                         bus_space_write_1(t,h,SWS_RW,reg+0x40);
172                         return bus_space_read_1(t,h,SWS_HSCX0);
173                 default:
174                         return 0;
175         }
176 }
177
178 /* attach callback routine */
179 int
180 isic_attach_sws(device_t dev)
181 {
182         int unit = device_get_unit(dev);
183         struct l1_softc *sc = &l1_sc[unit];     
184         
185         struct i4b_info * info = &(sc->sc_resources);
186         bus_space_tag_t    t = rman_get_bustag(info->io_base[0]);
187         bus_space_handle_t h = rman_get_bushandle(info->io_base[0]);
188
189         /* fill in l1_softc structure */
190         sc->readreg     = sws_read_reg;
191         sc->writereg    = sws_write_reg;
192         sc->readfifo    = sws_read_fifo;
193         sc->writefifo   = sws_write_fifo;
194         sc->clearirq    = NULL;
195         sc->sc_cardtyp  = CARD_TYPEP_SWS;
196         sc->sc_bustyp   = BUS_TYPE_IOM2;
197         sc->sc_ipac     = 0;
198         sc->sc_bfifolen = HSCX_FIFO_LEN;
199
200         /* 
201          * Read HSCX A/B VSTR.  Expected value for the SWS PnP card is
202          * 0x05 ( = version 2.1 ) in the least significant bits.
203          */
204
205         if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
206             ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
207         {
208                 printf("isic%d: HSCX VSTR test failed for SWS PnP\n",
209                         sc->sc_unit);
210                 printf("isic%d: HSC0: VSTR: %#x\n",
211                         sc->sc_unit, HSCX_READ(0, H_VSTR));
212                 printf("isic%d: HSC1: VSTR: %#x\n",
213                         sc->sc_unit, HSCX_READ(1, H_VSTR));
214                 return (ENXIO);
215         }                   
216
217         /* reset card */
218         bus_space_write_1(t,h,SWS_RESON,0x3);
219         DELAY(SEC_DELAY / 5);
220         bus_space_write_1(t,h,SWS_RESOFF,0x0);
221         DELAY(SEC_DELAY / 5);
222
223         return(0);
224 }
225 #endif /* defined(SEDLBAUER) && NISIC > 0 */