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

TOMOYO Linux Cross Reference
Linux/sound/isa/wavefront/wavefront_fx.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/isa/wavefront/wavefront_fx.c (Architecture ppc) and /sound/isa/wavefront/wavefront_fx.c (Architecture alpha)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*                                                  2 /*
  3  *  Copyright (c) 1998-2002 by Paul Davis <pbd      3  *  Copyright (c) 1998-2002 by Paul Davis <pbd@op.net>
  4  */                                                 4  */
  5                                                     5 
  6 #include <linux/io.h>                               6 #include <linux/io.h>
  7 #include <linux/init.h>                             7 #include <linux/init.h>
  8 #include <linux/time.h>                             8 #include <linux/time.h>
  9 #include <linux/wait.h>                             9 #include <linux/wait.h>
 10 #include <linux/slab.h>                            10 #include <linux/slab.h>
 11 #include <linux/module.h>                          11 #include <linux/module.h>
 12 #include <linux/firmware.h>                        12 #include <linux/firmware.h>
 13 #include <sound/core.h>                            13 #include <sound/core.h>
 14 #include <sound/snd_wavefront.h>                   14 #include <sound/snd_wavefront.h>
 15 #include <sound/initval.h>                         15 #include <sound/initval.h>
 16                                                    16 
 17 /* Control bits for the Load Control Register      17 /* Control bits for the Load Control Register
 18  */                                                18  */
 19                                                    19 
 20 #define FX_LSB_TRANSFER 0x01    /* transfer af     20 #define FX_LSB_TRANSFER 0x01    /* transfer after DSP LSB byte written */
 21 #define FX_MSB_TRANSFER 0x02    /* transfer af     21 #define FX_MSB_TRANSFER 0x02    /* transfer after DSP MSB byte written */
 22 #define FX_AUTO_INCR    0x04    /* auto-increm     22 #define FX_AUTO_INCR    0x04    /* auto-increment DSP address after transfer */
 23                                                    23 
 24 #define WAIT_IDLE       0xff                       24 #define WAIT_IDLE       0xff
 25                                                    25 
 26 static int                                         26 static int
 27 wavefront_fx_idle (snd_wavefront_t *dev)           27 wavefront_fx_idle (snd_wavefront_t *dev)
 28                                                    28 
 29 {                                                  29 {
 30         int i;                                     30         int i;
 31         unsigned int x = 0x80;                     31         unsigned int x = 0x80;
 32                                                    32 
 33         for (i = 0; i < 1000; i++) {               33         for (i = 0; i < 1000; i++) {
 34                 x = inb (dev->fx_status);          34                 x = inb (dev->fx_status);
 35                 if ((x & 0x80) == 0) {             35                 if ((x & 0x80) == 0) {
 36                         break;                     36                         break;
 37                 }                                  37                 }
 38         }                                          38         }
 39                                                    39 
 40         if (x & 0x80) {                            40         if (x & 0x80) {
 41                 dev_err(dev->card->dev, "FX de     41                 dev_err(dev->card->dev, "FX device never idle.\n");
 42                 return 0;                          42                 return 0;
 43         }                                          43         }
 44                                                    44 
 45         return (1);                                45         return (1);
 46 }                                                  46 }
 47                                                    47 
 48 static void                                        48 static void
 49 wavefront_fx_mute (snd_wavefront_t *dev, int o     49 wavefront_fx_mute (snd_wavefront_t *dev, int onoff)
 50                                                    50 
 51 {                                                  51 {
 52         if (!wavefront_fx_idle(dev)) {             52         if (!wavefront_fx_idle(dev)) {
 53                 return;                            53                 return;
 54         }                                          54         }
 55                                                    55 
 56         outb (onoff ? 0x02 : 0x00, dev->fx_op)     56         outb (onoff ? 0x02 : 0x00, dev->fx_op);
 57 }                                                  57 }
 58                                                    58 
 59 static int                                         59 static int
 60 wavefront_fx_memset (snd_wavefront_t *dev,         60 wavefront_fx_memset (snd_wavefront_t *dev,
 61                      int page,                     61                      int page,
 62                      int addr,                     62                      int addr,
 63                      int cnt,                      63                      int cnt,
 64                      unsigned short *data)         64                      unsigned short *data)
 65 {                                                  65 {
 66         if (page < 0 || page > 7) {                66         if (page < 0 || page > 7) {
 67                 dev_err(dev->card->dev,            67                 dev_err(dev->card->dev,
 68                         "FX memset: page must      68                         "FX memset: page must be >= 0 and <= 7\n");
 69                 return -EINVAL;                    69                 return -EINVAL;
 70         }                                          70         }
 71                                                    71 
 72         if (addr < 0 || addr > 0x7f) {             72         if (addr < 0 || addr > 0x7f) {
 73                 dev_err(dev->card->dev,            73                 dev_err(dev->card->dev,
 74                         "FX memset: addr must      74                         "FX memset: addr must be >= 0 and <= 7f\n");
 75                 return -EINVAL;                    75                 return -EINVAL;
 76         }                                          76         }
 77                                                    77 
 78         if (cnt == 1) {                            78         if (cnt == 1) {
 79                                                    79 
 80                 outb (FX_LSB_TRANSFER, dev->fx     80                 outb (FX_LSB_TRANSFER, dev->fx_lcr);
 81                 outb (page, dev->fx_dsp_page);     81                 outb (page, dev->fx_dsp_page);
 82                 outb (addr, dev->fx_dsp_addr);     82                 outb (addr, dev->fx_dsp_addr);
 83                 outb ((data[0] >> 8), dev->fx_     83                 outb ((data[0] >> 8), dev->fx_dsp_msb);
 84                 outb ((data[0] & 0xff), dev->f     84                 outb ((data[0] & 0xff), dev->fx_dsp_lsb);
 85                                                    85 
 86                 dev_err(dev->card->dev, "FX: a     86                 dev_err(dev->card->dev, "FX: addr %d:%x set to 0x%x\n",
 87                         page, addr, data[0]);      87                         page, addr, data[0]);
 88                                                    88 
 89         } else {                                   89         } else {
 90                 int i;                             90                 int i;
 91                                                    91 
 92                 outb (FX_AUTO_INCR|FX_LSB_TRAN     92                 outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr);
 93                 outb (page, dev->fx_dsp_page);     93                 outb (page, dev->fx_dsp_page);
 94                 outb (addr, dev->fx_dsp_addr);     94                 outb (addr, dev->fx_dsp_addr);
 95                                                    95 
 96                 for (i = 0; i < cnt; i++) {        96                 for (i = 0; i < cnt; i++) {
 97                         outb ((data[i] >> 8),      97                         outb ((data[i] >> 8), dev->fx_dsp_msb);
 98                         outb ((data[i] & 0xff)     98                         outb ((data[i] & 0xff), dev->fx_dsp_lsb);
 99                         if (!wavefront_fx_idle     99                         if (!wavefront_fx_idle (dev)) {
100                                 break;            100                                 break;
101                         }                         101                         }
102                 }                                 102                 }
103                                                   103 
104                 if (i != cnt) {                   104                 if (i != cnt) {
105                         dev_err(dev->card->dev    105                         dev_err(dev->card->dev,
106                                 "FX memset (0x    106                                 "FX memset (0x%x, 0x%x, 0x%lx, %d) incomplete\n",
107                                 page, addr, (u    107                                 page, addr, (unsigned long) data, cnt);
108                         return -EIO;              108                         return -EIO;
109                 }                                 109                 }
110         }                                         110         }
111                                                   111 
112         return 0;                                 112         return 0;
113 }                                                 113 }
114                                                   114 
115 int                                               115 int
116 snd_wavefront_fx_detect (snd_wavefront_t *dev)    116 snd_wavefront_fx_detect (snd_wavefront_t *dev)
117                                                   117 
118 {                                                 118 {
119         /* This is a crude check, but its the     119         /* This is a crude check, but its the best one I have for now.
120            Certainly on the Maui and the Trope    120            Certainly on the Maui and the Tropez, wavefront_fx_idle() will
121            report "never idle", which suggests    121            report "never idle", which suggests that this test should
122            work OK.                               122            work OK.
123         */                                        123         */
124                                                   124 
125         if (inb (dev->fx_status) & 0x80) {        125         if (inb (dev->fx_status) & 0x80) {
126                 dev_err(dev->card->dev, "Hmm,     126                 dev_err(dev->card->dev, "Hmm, probably a Maui or Tropez.\n");
127                 return -1;                        127                 return -1;
128         }                                         128         }
129                                                   129 
130         return 0;                                 130         return 0;
131 }                                                 131 }
132                                                   132 
133 int                                               133 int
134 snd_wavefront_fx_open (struct snd_hwdep *hw, s    134 snd_wavefront_fx_open (struct snd_hwdep *hw, struct file *file)
135                                                   135 
136 {                                                 136 {
137         if (!try_module_get(hw->card->module))    137         if (!try_module_get(hw->card->module))
138                 return -EFAULT;                   138                 return -EFAULT;
139         file->private_data = hw;                  139         file->private_data = hw;
140         return 0;                                 140         return 0;
141 }                                                 141 }
142                                                   142 
143 int                                               143 int 
144 snd_wavefront_fx_release (struct snd_hwdep *hw    144 snd_wavefront_fx_release (struct snd_hwdep *hw, struct file *file)
145                                                   145 
146 {                                                 146 {
147         module_put(hw->card->module);             147         module_put(hw->card->module);
148         return 0;                                 148         return 0;
149 }                                                 149 }
150                                                   150 
151 int                                               151 int
152 snd_wavefront_fx_ioctl (struct snd_hwdep *sdev    152 snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
153                         unsigned int cmd, unsi    153                         unsigned int cmd, unsigned long arg)
154                                                   154 
155 {                                                 155 {
156         struct snd_card *card;                    156         struct snd_card *card;
157         snd_wavefront_card_t *acard;              157         snd_wavefront_card_t *acard;
158         snd_wavefront_t *dev;                     158         snd_wavefront_t *dev;
159         wavefront_fx_info r;                      159         wavefront_fx_info r;
160         unsigned short *page_data = NULL;         160         unsigned short *page_data = NULL;
161         unsigned short *pd;                       161         unsigned short *pd;
162         int err = 0;                              162         int err = 0;
163                                                   163 
164         card = sdev->card;                        164         card = sdev->card;
165         if (snd_BUG_ON(!card))                    165         if (snd_BUG_ON(!card))
166                 return -ENODEV;                   166                 return -ENODEV;
167         if (snd_BUG_ON(!card->private_data))      167         if (snd_BUG_ON(!card->private_data))
168                 return -ENODEV;                   168                 return -ENODEV;
169                                                   169 
170         acard = card->private_data;               170         acard = card->private_data;
171         dev = &acard->wavefront;                  171         dev = &acard->wavefront;
172                                                   172 
173         if (copy_from_user (&r, (void __user *    173         if (copy_from_user (&r, (void __user *)arg, sizeof (wavefront_fx_info)))
174                 return -EFAULT;                   174                 return -EFAULT;
175                                                   175 
176         switch (r.request) {                      176         switch (r.request) {
177         case WFFX_MUTE:                           177         case WFFX_MUTE:
178                 wavefront_fx_mute (dev, r.data    178                 wavefront_fx_mute (dev, r.data[0]);
179                 return -EIO;                      179                 return -EIO;
180                                                   180 
181         case WFFX_MEMSET:                         181         case WFFX_MEMSET:
182                 if (r.data[2] <= 0) {             182                 if (r.data[2] <= 0) {
183                         dev_err(dev->card->dev    183                         dev_err(dev->card->dev,
184                                 "cannot write     184                                 "cannot write <= 0 bytes to FX\n");
185                         return -EIO;              185                         return -EIO;
186                 } else if (r.data[2] == 1) {      186                 } else if (r.data[2] == 1) {
187                         pd = (unsigned short *    187                         pd = (unsigned short *) &r.data[3];
188                 } else {                          188                 } else {
189                         if (r.data[2] > 256) {    189                         if (r.data[2] > 256) {
190                                 dev_err(dev->c    190                                 dev_err(dev->card->dev,
191                                         "canno    191                                         "cannot write > 512 bytes to FX\n");
192                                 return -EIO;      192                                 return -EIO;
193                         }                         193                         }
194                         page_data = memdup_arr    194                         page_data = memdup_array_user((unsigned char __user *)
195                                                   195                                                       r.data[3],
196                                                   196                                                       r.data[2], sizeof(short));
197                         if (IS_ERR(page_data))    197                         if (IS_ERR(page_data))
198                                 return PTR_ERR    198                                 return PTR_ERR(page_data);
199                         pd = page_data;           199                         pd = page_data;
200                 }                                 200                 }
201                                                   201 
202                 err = wavefront_fx_memset (dev    202                 err = wavefront_fx_memset (dev,
203                              r.data[0], /* pag    203                              r.data[0], /* page */
204                              r.data[1], /* add    204                              r.data[1], /* addr */
205                              r.data[2], /* cnt    205                              r.data[2], /* cnt */
206                              pd);                 206                              pd);
207                 kfree(page_data);                 207                 kfree(page_data);
208                 break;                            208                 break;
209                                                   209 
210         default:                                  210         default:
211                 dev_err(dev->card->dev, "FX: i    211                 dev_err(dev->card->dev, "FX: ioctl %d not yet supported\n",
212                         r.request);               212                         r.request);
213                 return -ENOTTY;                   213                 return -ENOTTY;
214         }                                         214         }
215         return err;                               215         return err;
216 }                                                 216 }
217                                                   217 
218 /* YSS225 initialization.                         218 /* YSS225 initialization.
219                                                   219 
220    This code was developed using DOSEMU. The T    220    This code was developed using DOSEMU. The Turtle Beach SETUPSND
221    utility was run with I/O tracing in DOSEMU     221    utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
222    of the port I/O done, using the Yamaha faxb    222    of the port I/O done, using the Yamaha faxback document as a guide
223    to add more logic to the code. Its really p    223    to add more logic to the code. Its really pretty weird.
224                                                   224 
225    This is the approach of just dumping the wh    225    This is the approach of just dumping the whole I/O
226    sequence as a series of port/value pairs an    226    sequence as a series of port/value pairs and a simple loop
227    that outputs it.                               227    that outputs it.
228 */                                                228 */
229                                                   229 
230 int                                               230 int
231 snd_wavefront_fx_start (snd_wavefront_t *dev)     231 snd_wavefront_fx_start (snd_wavefront_t *dev)
232 {                                                 232 {
233         unsigned int i;                           233         unsigned int i;
234         int err;                                  234         int err;
235         const struct firmware *firmware = NULL    235         const struct firmware *firmware = NULL;
236                                                   236 
237         if (dev->fx_initialized)                  237         if (dev->fx_initialized)
238                 return 0;                         238                 return 0;
239                                                   239 
240         err = request_firmware(&firmware, "yam    240         err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
241                                dev->card->dev)    241                                dev->card->dev);
242         if (err < 0) {                            242         if (err < 0) {
243                 err = -1;                         243                 err = -1;
244                 goto out;                         244                 goto out;
245         }                                         245         }
246                                                   246 
247         for (i = 0; i + 1 < firmware->size; i     247         for (i = 0; i + 1 < firmware->size; i += 2) {
248                 if (firmware->data[i] >= 8 &&     248                 if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
249                         outb(firmware->data[i     249                         outb(firmware->data[i + 1],
250                              dev->base + firmw    250                              dev->base + firmware->data[i]);
251                 } else if (firmware->data[i] =    251                 } else if (firmware->data[i] == WAIT_IDLE) {
252                         if (!wavefront_fx_idle    252                         if (!wavefront_fx_idle(dev)) {
253                                 err = -1;         253                                 err = -1;
254                                 goto out;         254                                 goto out;
255                         }                         255                         }
256                 } else {                          256                 } else {
257                         dev_err(dev->card->dev    257                         dev_err(dev->card->dev,
258                                 "invalid addre    258                                 "invalid address in register data\n");
259                         err = -1;                 259                         err = -1;
260                         goto out;                 260                         goto out;
261                 }                                 261                 }
262         }                                         262         }
263                                                   263 
264         dev->fx_initialized = 1;                  264         dev->fx_initialized = 1;
265         err = 0;                                  265         err = 0;
266                                                   266 
267 out:                                              267 out:
268         release_firmware(firmware);               268         release_firmware(firmware);
269         return err;                               269         return err;
270 }                                                 270 }
271                                                   271 
272 MODULE_FIRMWARE("yamaha/yss225_registers.bin")    272 MODULE_FIRMWARE("yamaha/yss225_registers.bin");
273                                                   273 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php