~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/ice1712/hoontech.c

Version: ~ [ linux-5.18 ] ~ [ linux-5.17.9 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.41 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.117 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.195 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.244 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.280 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.315 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
  3  *
  4  *   Lowlevel functions for Hoontech STDSP24
  5  *
  6  *      Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
  7  *
  8  *   This program is free software; you can redistribute it and/or modify
  9  *   it under the terms of the GNU General Public License as published by
 10  *   the Free Software Foundation; either version 2 of the License, or
 11  *   (at your option) any later version.
 12  *
 13  *   This program is distributed in the hope that it will be useful,
 14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16  *   GNU General Public License for more details.
 17  *
 18  *   You should have received a copy of the GNU General Public License
 19  *   along with this program; if not, write to the Free Software
 20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 21  *
 22  */      
 23 
 24 #include <linux/delay.h>
 25 #include <linux/interrupt.h>
 26 #include <linux/init.h>
 27 #include <linux/slab.h>
 28 #include <linux/mutex.h>
 29 
 30 #include <sound/core.h>
 31 
 32 #include "ice1712.h"
 33 #include "hoontech.h"
 34 
 35 /* Hoontech-specific setting */
 36 struct hoontech_spec {
 37         unsigned char boxbits[4];
 38         unsigned int config;
 39         unsigned short boxconfig[4];
 40 };
 41 
 42 static void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
 43 {
 44         byte |= ICE1712_STDSP24_CLOCK_BIT;
 45         udelay(100);
 46         snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
 47         byte &= ~ICE1712_STDSP24_CLOCK_BIT;
 48         udelay(100);
 49         snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
 50         byte |= ICE1712_STDSP24_CLOCK_BIT;
 51         udelay(100);
 52         snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
 53 }
 54 
 55 static void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
 56 {
 57         struct hoontech_spec *spec = ice->spec;
 58         mutex_lock(&ice->gpio_mutex);
 59         ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
 60         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
 61         mutex_unlock(&ice->gpio_mutex);
 62 }
 63 
 64 static void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
 65 {
 66         struct hoontech_spec *spec = ice->spec;
 67         mutex_lock(&ice->gpio_mutex);
 68         ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
 69         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 70         mutex_unlock(&ice->gpio_mutex);
 71 }
 72 
 73 static void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
 74 {
 75         struct hoontech_spec *spec = ice->spec;
 76         mutex_lock(&ice->gpio_mutex);
 77         ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
 78         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 79         mutex_unlock(&ice->gpio_mutex);
 80 }
 81 
 82 static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
 83 {
 84         struct hoontech_spec *spec = ice->spec;
 85 
 86         mutex_lock(&ice->gpio_mutex);
 87 
 88         /* select box */
 89         ICE1712_STDSP24_0_BOX(spec->boxbits, box);
 90         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
 91 
 92         /* prepare for write */
 93         if (chn == 3)
 94                 ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
 95         ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
 96         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 97         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 98 
 99         ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
100         ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
101         ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
102         ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
103         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
104         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
105         udelay(100);
106         if (chn == 3) {
107                 ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
108                 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
109         } else {
110                 switch (chn) {
111                 case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
112                 case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
113                 case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
114                 }
115                 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
116         }
117         udelay(100);
118         ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
119         ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
120         ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
121         ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
122         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
123         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
124         udelay(100);
125 
126         ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
127         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
128 
129         mutex_unlock(&ice->gpio_mutex);
130 }
131 
132 static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
133 {
134         struct hoontech_spec *spec = ice->spec;
135 
136         mutex_lock(&ice->gpio_mutex);
137 
138         /* select box */
139         ICE1712_STDSP24_0_BOX(spec->boxbits, box);
140         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
141 
142         ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
143         ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
144         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
145         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
146 
147         udelay(100);
148         
149         ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
150         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
151         
152         mdelay(10);
153         
154         ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
155         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
156 
157         mutex_unlock(&ice->gpio_mutex);
158 }
159 
160 static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
161 {
162         struct hoontech_spec *spec = ice->spec;
163         mutex_lock(&ice->gpio_mutex);
164         ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
165         snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
166         mutex_unlock(&ice->gpio_mutex);
167 }
168 
169 static int hoontech_init(struct snd_ice1712 *ice, bool staudio)
170 {
171         struct hoontech_spec *spec;
172         int box, chn;
173 
174         ice->num_total_dacs = 8;
175         ice->num_total_adcs = 8;
176 
177         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
178         if (!spec)
179                 return -ENOMEM;
180         ice->spec = spec;
181 
182         ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
183         ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
184         ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
185         ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
186 
187         ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
188         ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
189         ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
190         ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
191         ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
192         
193         ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
194         ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
195         ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
196         ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
197         ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
198 
199         ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
200         ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
201         ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
202         ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
203         ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
204 
205         /* let's go - activate only functions in first box */
206         if (staudio)
207                 spec->config = ICE1712_STDSP24_MUTE;
208         else
209                 spec->config = 0;
210                             /* ICE1712_STDSP24_MUTE |
211                                ICE1712_STDSP24_INSEL |
212                                ICE1712_STDSP24_DAREAR; */
213         /*  These boxconfigs have caused problems in the past.
214          *  The code is not optimal, but should now enable a working config to
215          *  be achieved.
216          *  ** MIDI IN can only be configured on one box **
217          *  ICE1712_STDSP24_BOX_MIDI1 needs to be set for that box.
218          *  Tests on a ADAC2000 box suggest the box config flags do not
219          *  work as would be expected, and the inputs are crossed.
220          *  Setting ICE1712_STDSP24_BOX_MIDI1 and ICE1712_STDSP24_BOX_MIDI2
221          *  on the same box connects MIDI-In to both 401 uarts; both outputs
222          *  are then active on all boxes.
223          *  The default config here sets up everything on the first box.
224          *  Alan Horstmann  5.2.2008
225          */
226         spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
227                                      ICE1712_STDSP24_BOX_CHN2 |
228                                      ICE1712_STDSP24_BOX_CHN3 |
229                                      ICE1712_STDSP24_BOX_CHN4 |
230                                      ICE1712_STDSP24_BOX_MIDI1 |
231                                      ICE1712_STDSP24_BOX_MIDI2;
232         if (staudio) {
233                 spec->boxconfig[1] =
234                 spec->boxconfig[2] =
235                 spec->boxconfig[3] = spec->boxconfig[0];
236         } else {
237                 spec->boxconfig[1] =
238                 spec->boxconfig[2] =
239                 spec->boxconfig[3] = 0;
240         }
241 
242         snd_ice1712_stdsp24_darear(ice,
243                 (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
244         snd_ice1712_stdsp24_mute(ice,
245                 (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
246         snd_ice1712_stdsp24_insel(ice,
247                 (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
248         for (box = 0; box < 4; box++) {
249                 if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
250                         snd_ice1712_stdsp24_midi2(ice, 1);
251                 for (chn = 0; chn < 4; chn++)
252                         snd_ice1712_stdsp24_box_channel(ice, box, chn,
253                                 (spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
254                 if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1)
255                         snd_ice1712_stdsp24_box_midi(ice, box, 1);
256         }
257 
258         return 0;
259 }
260 
261 static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
262 {
263         return hoontech_init(ice, false);
264 }
265 
266 static int snd_ice1712_staudio_init(struct snd_ice1712 *ice)
267 {
268         return hoontech_init(ice, true);
269 }
270 
271 /*
272  * AK4524 access
273  */
274 
275 /* start callback for STDSP24 with modified hardware */
276 static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
277 {
278         struct snd_ice1712 *ice = ak->private_data[0];
279         unsigned char tmp;
280         snd_ice1712_save_gpio_status(ice);
281         tmp =   ICE1712_STDSP24_SERIAL_DATA |
282                 ICE1712_STDSP24_SERIAL_CLOCK |
283                 ICE1712_STDSP24_AK4524_CS;
284         snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
285                           ice->gpio.direction | tmp);
286         snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
287 }
288 
289 static int snd_ice1712_value_init(struct snd_ice1712 *ice)
290 {
291         /* Hoontech STDSP24 with modified hardware */
292         static const struct snd_akm4xxx akm_stdsp24_mv = {
293                 .num_adcs = 2,
294                 .num_dacs = 2,
295                 .type = SND_AK4524,
296                 .ops = {
297                         .lock = stdsp24_ak4524_lock
298                 }
299         };
300 
301         static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = {
302                 .caddr = 2,
303                 .cif = 1, /* CIF high */
304                 .data_mask = ICE1712_STDSP24_SERIAL_DATA,
305                 .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK,
306                 .cs_mask = ICE1712_STDSP24_AK4524_CS,
307                 .cs_addr = ICE1712_STDSP24_AK4524_CS,
308                 .cs_none = 0,
309                 .add_flags = 0,
310         };
311 
312         int err;
313         struct snd_akm4xxx *ak;
314 
315         /* set the analog DACs */
316         ice->num_total_dacs = 2;
317 
318         /* set the analog ADCs */
319         ice->num_total_adcs = 2;
320         
321         /* analog section */
322         ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
323         if (! ak)
324                 return -ENOMEM;
325         ice->akm_codecs = 1;
326 
327         err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice);
328         if (err < 0)
329                 return err;
330 
331         /* ak4524 controls */
332         return snd_ice1712_akm4xxx_build_controls(ice);
333 }
334 
335 static int snd_ice1712_ez8_init(struct snd_ice1712 *ice)
336 {
337         ice->gpio.write_mask = ice->eeprom.gpiomask;
338         ice->gpio.direction = ice->eeprom.gpiodir;
339         snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
340         snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
341         snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
342         return 0;
343 }
344 
345 
346 /* entry point */
347 struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = {
348         {
349                 .subvendor = ICE1712_SUBDEVICE_STDSP24,
350                 .name = "Hoontech SoundTrack Audio DSP24",
351                 .model = "dsp24",
352                 .chip_init = snd_ice1712_hoontech_init,
353                 .mpu401_1_name = "MIDI-1 Hoontech/STA DSP24",
354                 .mpu401_2_name = "MIDI-2 Hoontech/STA DSP24",
355         },
356         {
357                 .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE,   /* a dummy id */
358                 .name = "Hoontech SoundTrack Audio DSP24 Value",
359                 .model = "dsp24_value",
360                 .chip_init = snd_ice1712_value_init,
361         },
362         {
363                 .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
364                 .name = "Hoontech STA DSP24 Media 7.1",
365                 .model = "dsp24_71",
366                 .chip_init = snd_ice1712_hoontech_init,
367         },
368         {
369                 .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8,       /* a dummy id */
370                 .name = "Event Electronics EZ8",
371                 .model = "ez8",
372                 .chip_init = snd_ice1712_ez8_init,
373         },
374         {
375                 /* STAudio ADCIII has the same SSID as Hoontech StA DSP24,
376                  * thus identified only via the explicit model option
377                  */
378                 .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII,  /* a dummy id */
379                 .name = "STAudio ADCIII",
380                 .model = "staudio",
381                 .chip_init = snd_ice1712_staudio_init,
382         },
383         { } /* terminator */
384 };
385 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp