1 /* $Id: dmy.c,v 1.10 2001/10/08 22:19:50 davem Exp $
2  * drivers/sbus/audio/dummy.c
3  *
4  * Copyright 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
5  *
6  * This is a dummy lowlevel driver. Consider it a distant cousin of
7  * /proc/audio; It pretends to be a piece of audio hardware, and writes
8  * to a file instead. (or will shortly)
9  */
10 
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/errno.h>
15 #include <linux/interrupt.h>
16 #include <linux/slab.h>
17 #include <linux/init.h>
18 #include <linux/soundcard.h>
19 #include <linux/delay.h>
20 #include <asm/openprom.h>
21 #include <asm/oplib.h>
22 #include <asm/system.h>
23 #include <asm/io.h>
24 #include <asm/pgtable.h>
25 #include <asm/sbus.h>
26 
27 #include <asm/audioio.h>
28 #include "dummy.h"
29 
30 #define MAX_DRIVERS 1
31 static struct sparcaudio_driver drivers[MAX_DRIVERS];
32 static int num_drivers;
33 
34 static int dummy_play_gain(struct sparcaudio_driver *drv, int value,
35                             unsigned char balance);
36 static int dummy_record_gain(struct sparcaudio_driver *drv, int value,
37                             unsigned char balance);
38 static int dummy_output_muted(struct sparcaudio_driver *drv, int value);
39 static int dummy_attach(struct sparcaudio_driver *drv) __init;
40 
41 static int
dummy_set_output_encoding(struct sparcaudio_driver * drv,int value)42 dummy_set_output_encoding(struct sparcaudio_driver *drv, int value)
43 {
44         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
45 
46         if (value != 0) {
47                 dummy_chip->perchip_info.play.encoding = value;
48                 return 0;
49         }
50         return -EINVAL;
51 }
52 
53 static int
dummy_set_input_encoding(struct sparcaudio_driver * drv,int value)54 dummy_set_input_encoding(struct sparcaudio_driver *drv, int value)
55 {
56         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
57 
58         if (value != 0) {
59                 dummy_chip->perchip_info.record.encoding = value;
60                 return 0;
61         }
62         return -EINVAL;
63 }
64 
dummy_get_output_encoding(struct sparcaudio_driver * drv)65 static int dummy_get_output_encoding(struct sparcaudio_driver *drv)
66 {
67         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
68 
69         return dummy_chip->perchip_info.play.encoding;
70 }
71 
dummy_get_input_encoding(struct sparcaudio_driver * drv)72 static int dummy_get_input_encoding(struct sparcaudio_driver *drv)
73 {
74         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
75 
76         return dummy_chip->perchip_info.record.encoding;
77 }
78 
79 static int
dummy_set_output_rate(struct sparcaudio_driver * drv,int value)80 dummy_set_output_rate(struct sparcaudio_driver *drv, int value)
81 {
82         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
83 
84         if (value != 0) {
85                 dummy_chip->perchip_info.play.sample_rate = value;
86                 return 0;
87         }
88         return -EINVAL;
89 }
90 
91 static int
dummy_set_input_rate(struct sparcaudio_driver * drv,int value)92 dummy_set_input_rate(struct sparcaudio_driver *drv, int value)
93 {
94         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
95 
96         if (value != 0) {
97                 dummy_chip->perchip_info.record.sample_rate = value;
98                 return 0;
99         }
100         return -EINVAL;
101 }
102 
dummy_get_output_rate(struct sparcaudio_driver * drv)103 static int dummy_get_output_rate(struct sparcaudio_driver *drv)
104 {
105         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
106 
107         return dummy_chip->perchip_info.play.sample_rate;
108 }
109 
dummy_get_input_rate(struct sparcaudio_driver * drv)110 static int dummy_get_input_rate(struct sparcaudio_driver *drv)
111 {
112         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
113 
114         return dummy_chip->perchip_info.record.sample_rate;
115 }
116 
117 /* Generically we support 4 channels. This does 2 */
118 static int
dummy_set_output_channels(struct sparcaudio_driver * drv,int value)119 dummy_set_output_channels(struct sparcaudio_driver *drv, int value)
120 {
121         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
122 
123         switch (value) {
124         case 1:
125         case 2:
126                 break;
127         default:
128                 return -(EINVAL);
129         };
130 
131         dummy_chip->perchip_info.play.channels = value;
132         return 0;
133 }
134 
135 /* Generically we support 4 channels. This does 2 */
136 static int
dummy_set_input_channels(struct sparcaudio_driver * drv,int value)137 dummy_set_input_channels(struct sparcaudio_driver *drv, int value)
138 {
139         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
140 
141         switch (value) {
142         case 1:
143         case 2:
144                 break;
145         default:
146                 return -(EINVAL);
147         };
148 
149         dummy_chip->perchip_info.record.channels = value;
150         return 0;
151 }
152 
dummy_get_input_channels(struct sparcaudio_driver * drv)153 static int dummy_get_input_channels(struct sparcaudio_driver *drv)
154 {
155         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
156 
157         return dummy_chip->perchip_info.record.channels;
158 }
159 
dummy_get_output_channels(struct sparcaudio_driver * drv)160 static int dummy_get_output_channels(struct sparcaudio_driver *drv)
161 {
162         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
163 
164         return dummy_chip->perchip_info.play.channels;
165 }
166 
dummy_get_output_precision(struct sparcaudio_driver * drv)167 static int dummy_get_output_precision(struct sparcaudio_driver *drv)
168 {
169         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
170 
171         return dummy_chip->perchip_info.play.precision;
172 }
173 
dummy_get_input_precision(struct sparcaudio_driver * drv)174 static int dummy_get_input_precision(struct sparcaudio_driver *drv)
175 {
176         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
177 
178         return dummy_chip->perchip_info.record.precision;
179 }
180 
dummy_set_output_precision(struct sparcaudio_driver * drv,int val)181 static int dummy_set_output_precision(struct sparcaudio_driver *drv, int val)
182 {
183         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
184 
185         dummy_chip->perchip_info.play.precision = val;
186         return dummy_chip->perchip_info.play.precision;
187 }
188 
dummy_set_input_precision(struct sparcaudio_driver * drv,int val)189 static int dummy_set_input_precision(struct sparcaudio_driver *drv, int val)
190 {
191         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
192 
193         dummy_chip->perchip_info.record.precision = val;
194         return dummy_chip->perchip_info.record.precision;
195 }
196 
197 /* Set output mute */
dummy_output_muted(struct sparcaudio_driver * drv,int value)198 static int dummy_output_muted(struct sparcaudio_driver *drv, int value)
199 {
200         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
201 
202         if (!value)
203                 dummy_chip->perchip_info.output_muted = 0;
204         else
205                 dummy_chip->perchip_info.output_muted = 1;
206 
207         return 0;
208 }
209 
dummy_get_output_muted(struct sparcaudio_driver * drv)210 static int dummy_get_output_muted(struct sparcaudio_driver *drv)
211 {
212         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
213 
214         return dummy_chip->perchip_info.output_muted;
215 }
216 
dummy_get_formats(struct sparcaudio_driver * drv)217 static int dummy_get_formats(struct sparcaudio_driver *drv)
218 {
219         return (AFMT_MU_LAW | AFMT_A_LAW |
220                 AFMT_U8 | AFMT_IMA_ADPCM |
221                 AFMT_S16_LE | AFMT_S16_BE);
222 }
223 
dummy_get_output_ports(struct sparcaudio_driver * drv)224 static int dummy_get_output_ports(struct sparcaudio_driver *drv)
225 {
226         return (AUDIO_LINE_OUT | AUDIO_SPEAKER | AUDIO_HEADPHONE);
227 }
228 
dummy_get_input_ports(struct sparcaudio_driver * drv)229 static int dummy_get_input_ports(struct sparcaudio_driver *drv)
230 {
231         return (AUDIO_ANALOG_LOOPBACK);
232 }
233 
234 /* Set chip "output" port */
dummy_set_output_port(struct sparcaudio_driver * drv,int value)235 static int dummy_set_output_port(struct sparcaudio_driver *drv, int value)
236 {
237         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
238 
239         dummy_chip->perchip_info.play.port = value;
240         return value;
241 }
242 
dummy_set_input_port(struct sparcaudio_driver * drv,int value)243 static int dummy_set_input_port(struct sparcaudio_driver *drv, int value)
244 {
245         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
246 
247         dummy_chip->perchip_info.record.port = value;
248         return value;
249 }
250 
dummy_get_output_port(struct sparcaudio_driver * drv)251 static int dummy_get_output_port(struct sparcaudio_driver *drv)
252 {
253         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
254 
255         return dummy_chip->perchip_info.play.port;
256 }
257 
dummy_get_input_port(struct sparcaudio_driver * drv)258 static int dummy_get_input_port(struct sparcaudio_driver *drv)
259 {
260         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
261 
262         return dummy_chip->perchip_info.record.port;
263 }
264 
dummy_get_output_error(struct sparcaudio_driver * drv)265 static int dummy_get_output_error(struct sparcaudio_driver *drv)
266 {
267         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
268 
269         return (int) dummy_chip->perchip_info.play.error;
270 }
271 
dummy_get_input_error(struct sparcaudio_driver * drv)272 static int dummy_get_input_error(struct sparcaudio_driver *drv)
273 {
274         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
275 
276         return (int) dummy_chip->perchip_info.record.error;
277 }
278 
dummy_get_output_samples(struct sparcaudio_driver * drv)279 static int dummy_get_output_samples(struct sparcaudio_driver *drv)
280 {
281         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
282 
283         return dummy_chip->perchip_info.play.samples;
284 }
285 
dummy_get_output_pause(struct sparcaudio_driver * drv)286 static int dummy_get_output_pause(struct sparcaudio_driver *drv)
287 {
288         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
289 
290         return (int) dummy_chip->perchip_info.play.pause;
291 }
292 
dummy_set_output_volume(struct sparcaudio_driver * drv,int value)293 static int dummy_set_output_volume(struct sparcaudio_driver *drv, int value)
294 {
295         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
296 
297         dummy_play_gain(drv, value, dummy_chip->perchip_info.play.balance);
298         return 0;
299 }
300 
dummy_get_output_volume(struct sparcaudio_driver * drv)301 static int dummy_get_output_volume(struct sparcaudio_driver *drv)
302 {
303         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
304 
305         return dummy_chip->perchip_info.play.gain;
306 }
307 
dummy_set_output_balance(struct sparcaudio_driver * drv,int value)308 static int dummy_set_output_balance(struct sparcaudio_driver *drv, int value)
309 {
310         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
311 
312         dummy_chip->perchip_info.play.balance = value;
313         dummy_play_gain(drv, dummy_chip->perchip_info.play.gain,
314                         dummy_chip->perchip_info.play.balance);
315         return 0;
316 }
317 
dummy_get_output_balance(struct sparcaudio_driver * drv)318 static int dummy_get_output_balance(struct sparcaudio_driver *drv)
319 {
320         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
321 
322         return (int) dummy_chip->perchip_info.play.balance;
323 }
324 
325 /* Set chip play gain */
dummy_play_gain(struct sparcaudio_driver * drv,int value,unsigned char balance)326 static int dummy_play_gain(struct sparcaudio_driver *drv,
327                            int value, unsigned char balance)
328 {
329         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
330         int tmp = 0, r, l, r_adj, l_adj;
331 
332         r = l = value;
333         if (balance < AUDIO_MID_BALANCE) {
334                 r = (int) (value -
335                            ((AUDIO_MID_BALANCE - balance) << AUDIO_BALANCE_SHIFT));
336 
337                 if (r < 0)
338                         r = 0;
339         } else if (balance > AUDIO_MID_BALANCE) {
340                 l = (int) (value -
341                            ((balance - AUDIO_MID_BALANCE) << AUDIO_BALANCE_SHIFT));
342 
343                 if (l < 0)
344                         l = 0;
345         }
346         (l == 0) ? (l_adj = DUMMY_MAX_DEV_ATEN) : (l_adj = DUMMY_MAX_ATEN -
347                                                    (l * (DUMMY_MAX_ATEN + 1) /
348                                                     (AUDIO_MAX_GAIN + 1)));
349         (r == 0) ? (r_adj = DUMMY_MAX_DEV_ATEN) : (r_adj = DUMMY_MAX_ATEN -
350                                                    (r * (DUMMY_MAX_ATEN + 1) /
351                                                     (AUDIO_MAX_GAIN + 1)));
352         if ((value == 0) || (value == AUDIO_MAX_GAIN)) {
353                 tmp = value;
354         } else {
355                 if (value == l) {
356                         tmp = ((DUMMY_MAX_ATEN - l_adj) * (AUDIO_MAX_GAIN + 1) /
357                                (DUMMY_MAX_ATEN + 1));
358                 } else if (value == r) {
359                         tmp = ((DUMMY_MAX_ATEN - r_adj) * (AUDIO_MAX_GAIN + 1) /
360                                (DUMMY_MAX_ATEN + 1));
361                 }
362         }
363         dummy_chip->perchip_info.play.gain = tmp;
364         return 0;
365 }
366 
dummy_get_input_samples(struct sparcaudio_driver * drv)367 static int dummy_get_input_samples(struct sparcaudio_driver *drv)
368 {
369         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
370 
371         return dummy_chip->perchip_info.record.samples;
372 }
373 
dummy_get_input_pause(struct sparcaudio_driver * drv)374 static int dummy_get_input_pause(struct sparcaudio_driver *drv)
375 {
376         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
377 
378         return (int) dummy_chip->perchip_info.record.pause;
379 }
380 
dummy_set_monitor_volume(struct sparcaudio_driver * drv,int value)381 static int dummy_set_monitor_volume(struct sparcaudio_driver *drv, int value)
382 {
383         return 0;
384 }
385 
dummy_get_monitor_volume(struct sparcaudio_driver * drv)386 static int dummy_get_monitor_volume(struct sparcaudio_driver *drv)
387 {
388         return 0;
389 }
390 
dummy_set_input_volume(struct sparcaudio_driver * drv,int value)391 static int dummy_set_input_volume(struct sparcaudio_driver *drv, int value)
392 {
393         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
394 
395         dummy_record_gain(drv, value, dummy_chip->perchip_info.record.balance);
396         return 0;
397 }
398 
dummy_get_input_volume(struct sparcaudio_driver * drv)399 static int dummy_get_input_volume(struct sparcaudio_driver *drv)
400 {
401         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
402 
403         return dummy_chip->perchip_info.record.gain;
404 }
405 
dummy_set_input_balance(struct sparcaudio_driver * drv,int value)406 static int dummy_set_input_balance(struct sparcaudio_driver *drv, int value)
407 {
408         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
409 
410         dummy_chip->perchip_info.record.balance = value;
411         dummy_record_gain(drv, dummy_chip->perchip_info.record.gain,
412                           dummy_chip->perchip_info.play.balance);
413         return 0;
414 }
415 
dummy_get_input_balance(struct sparcaudio_driver * drv)416 static int dummy_get_input_balance(struct sparcaudio_driver *drv)
417 {
418         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
419 
420         return (int) dummy_chip->perchip_info.record.balance;
421 }
422 
dummy_record_gain(struct sparcaudio_driver * drv,int value,unsigned char balance)423 static int dummy_record_gain(struct sparcaudio_driver *drv,
424                              int value, unsigned char balance)
425 {
426         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
427         int tmp = 0, r, l, r_adj, l_adj;
428 
429         r = l = value;
430         if (balance < AUDIO_MID_BALANCE) {
431                 r = (int) (value -
432                            ((AUDIO_MID_BALANCE - balance) << AUDIO_BALANCE_SHIFT));
433 
434                 if (r < 0)
435                         r = 0;
436         } else if (balance > AUDIO_MID_BALANCE) {
437                 l = (int) (value -
438                            ((balance - AUDIO_MID_BALANCE) << AUDIO_BALANCE_SHIFT));
439 
440                 if (l < 0)
441                         l = 0;
442         }
443         (l == 0) ? (l_adj = DUMMY_MAX_DEV_ATEN) : (l_adj = DUMMY_MAX_ATEN -
444                                                    (l * (DUMMY_MAX_ATEN + 1) /
445                                                     (AUDIO_MAX_GAIN + 1)));
446         (r == 0) ? (r_adj = DUMMY_MAX_DEV_ATEN) : (r_adj = DUMMY_MAX_ATEN -
447                                                    (r * (DUMMY_MAX_ATEN + 1) /
448                                                     (AUDIO_MAX_GAIN + 1)));
449         if ((value == 0) || (value == AUDIO_MAX_GAIN)) {
450                 tmp = value;
451         } else {
452                 if (value == l) {
453                         tmp = ((DUMMY_MAX_ATEN - l_adj) * (AUDIO_MAX_GAIN + 1) /
454                                (DUMMY_MAX_ATEN + 1));
455                 } else if (value == r) {
456                         tmp = ((DUMMY_MAX_ATEN - r_adj) * (AUDIO_MAX_GAIN + 1) /
457                                (DUMMY_MAX_ATEN + 1));
458                 }
459         }
460         dummy_chip->perchip_info.record.gain = tmp;
461         return 0;
462 }
463 
464 /* Reset the audio chip to a sane state. */
dummy_chip_reset(struct sparcaudio_driver * drv)465 static void dummy_chip_reset(struct sparcaudio_driver *drv)
466 {
467         dummy_set_output_encoding(drv, AUDIO_ENCODING_ULAW);
468         dummy_set_output_rate(drv, DUMMY_RATE);
469         dummy_set_output_channels(drv, DUMMY_CHANNELS);
470         dummy_set_output_precision(drv, DUMMY_PRECISION);
471         dummy_set_output_balance(drv, AUDIO_MID_BALANCE);
472         dummy_set_output_volume(drv, DUMMY_DEFAULT_PLAYGAIN);
473         dummy_set_output_port(drv, AUDIO_SPEAKER);
474         dummy_output_muted(drv, 0);
475         dummy_set_input_encoding(drv, AUDIO_ENCODING_ULAW);
476         dummy_set_input_rate(drv, DUMMY_RATE);
477         dummy_set_input_channels(drv, DUMMY_CHANNELS);
478         dummy_set_input_precision(drv, DUMMY_PRECISION);
479         dummy_set_input_balance(drv, AUDIO_MID_BALANCE);
480         dummy_set_input_volume(drv, DUMMY_DEFAULT_PLAYGAIN);
481         dummy_set_input_port(drv, AUDIO_SPEAKER);
482 }
483 
dummy_open(struct inode * inode,struct file * file,struct sparcaudio_driver * drv)484 static int dummy_open(struct inode * inode, struct file * file, struct sparcaudio_driver *drv)
485 {
486         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
487 
488         /* Set the default audio parameters if not already in use. */
489         if (file->f_mode & FMODE_WRITE) {
490                 if (!(drv->flags & SDF_OPEN_WRITE) &&
491                     (dummy_chip->perchip_info.play.active == 0)) {
492                         dummy_chip->perchip_info.play.open = 1;
493                         dummy_chip->perchip_info.play.samples =
494                                 dummy_chip->perchip_info.play.error = 0;
495                 }
496         }
497 
498         if (file->f_mode & FMODE_READ) {
499                 if (!(drv->flags & SDF_OPEN_READ) &&
500                     (dummy_chip->perchip_info.record.active == 0)) {
501                         dummy_chip->perchip_info.record.open = 1;
502                         dummy_chip->perchip_info.record.samples =
503                                 dummy_chip->perchip_info.record.error = 0;
504                 }
505         }
506 
507         MOD_INC_USE_COUNT;
508 
509         return 0;
510 }
511 
dummy_release(struct inode * inode,struct file * file,struct sparcaudio_driver * drv)512 static void dummy_release(struct inode * inode, struct file * file, struct sparcaudio_driver *drv)
513 {
514         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
515 
516         if (file->f_mode & FMODE_WRITE) {
517                 dummy_chip->perchip_info.play.active =
518                         dummy_chip->perchip_info.play.open = 0;
519         }
520 
521         if (file->f_mode & FMODE_READ) {
522                 dummy_chip->perchip_info.record.active =
523                         dummy_chip->perchip_info.record.open = 0;
524         }
525 
526         MOD_DEC_USE_COUNT;
527 }
528 
dummy_output_done_task(void * arg)529 static void dummy_output_done_task(void * arg)
530 {
531         struct sparcaudio_driver *drv = (struct sparcaudio_driver *) arg;
532         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
533 
534         sparcaudio_output_done(drv, 1);
535         if (dummy_chip->perchip_info.record.active)
536                 sparcaudio_input_done(drv, 1);
537 }
538 
dummy_start_output(struct sparcaudio_driver * drv,__u8 * buffer,unsigned long count)539 static void dummy_start_output(struct sparcaudio_driver *drv, __u8 * buffer,
540                                unsigned long count)
541 {
542         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
543 
544         if (dummy_chip->perchip_info.play.pause || !count)
545                 return;
546 
547         dummy_chip->perchip_info.play.active = 1;
548 
549         /* fake an "interrupt" to deal with this block */
550         INIT_LIST_HEAD(&dummy_chip->tqueue.list);
551         dummy_chip->tqueue.sync = 0;
552         dummy_chip->tqueue.routine = dummy_output_done_task;
553         dummy_chip->tqueue.data = drv;
554 
555         queue_task(&dummy_chip->tqueue, &tq_immediate);
556         mark_bh(IMMEDIATE_BH);
557 }
558 
dummy_start_input(struct sparcaudio_driver * drv,__u8 * buffer,unsigned long count)559 static void dummy_start_input(struct sparcaudio_driver *drv, __u8 * buffer,
560                               unsigned long count)
561 {
562         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
563 
564         dummy_chip->perchip_info.record.active = 1;
565 }
566 
dummy_stop_output(struct sparcaudio_driver * drv)567 static void dummy_stop_output(struct sparcaudio_driver *drv)
568 {
569         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
570 
571         dummy_chip->perchip_info.play.active = 0;
572 }
573 
dummy_stop_input(struct sparcaudio_driver * drv)574 static void dummy_stop_input(struct sparcaudio_driver *drv)
575 {
576         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
577 
578         dummy_chip->perchip_info.record.active = 0;
579 }
580 
dummy_set_output_pause(struct sparcaudio_driver * drv,int value)581 static int dummy_set_output_pause(struct sparcaudio_driver *drv, int value)
582 {
583         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
584 
585         dummy_chip->perchip_info.play.pause = value;
586 
587         if (!value)
588                 sparcaudio_output_done(drv, 0);
589 
590         return value;
591 }
592 
dummy_set_input_pause(struct sparcaudio_driver * drv,int value)593 static int dummy_set_input_pause(struct sparcaudio_driver *drv, int value)
594 {
595         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
596 
597         dummy_chip->perchip_info.record.pause = value;
598 
599         /* This should probably cause play pause. */
600 
601         return value;
602 }
603 
dummy_set_input_error(struct sparcaudio_driver * drv,int value)604 static int dummy_set_input_error(struct sparcaudio_driver *drv, int value)
605 {
606         return 0;
607 }
608 
dummy_set_output_error(struct sparcaudio_driver * drv,int value)609 static int dummy_set_output_error(struct sparcaudio_driver *drv, int value)
610 {
611         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
612         int i;
613 
614         i = dummy_chip->perchip_info.play.error;
615         dummy_chip->perchip_info.play.error = value;
616         return i;
617 }
618 
dummy_set_output_samples(struct sparcaudio_driver * drv,int value)619 static int dummy_set_output_samples(struct sparcaudio_driver *drv, int value)
620 {
621         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
622         int i;
623 
624         i = dummy_chip->perchip_info.play.samples;
625         dummy_chip->perchip_info.play.samples = value;
626         return i;
627 }
628 
dummy_set_input_samples(struct sparcaudio_driver * drv,int value)629 static int dummy_set_input_samples(struct sparcaudio_driver *drv, int value)
630 {
631         struct dummy_chip *dummy_chip = (struct dummy_chip *) drv->private;
632         int i;
633 
634         i = dummy_chip->perchip_info.play.samples;
635         dummy_chip->perchip_info.record.samples = value;
636         return i;
637 }
638 
639 /* In order to fake things which care out, play we're a 4231 */
dummy_audio_getdev(struct sparcaudio_driver * drv,audio_device_t * audinfo)640 static void dummy_audio_getdev(struct sparcaudio_driver *drv,
641                                audio_device_t * audinfo)
642 {
643         strncpy(audinfo->name, "SUNW,cs4231", sizeof(audinfo->name) - 1);
644         strncpy(audinfo->version, "a", sizeof(audinfo->version) - 1);
645         strncpy(audinfo->config, "onboard1", sizeof(audinfo->config) - 1);
646 }
647 
648 
dummy_audio_getdev_sunos(struct sparcaudio_driver * drv)649 static int dummy_audio_getdev_sunos(struct sparcaudio_driver *drv)
650 {
651         return 5;
652 }
653 
654 static struct sparcaudio_operations dummy_ops = {
655 	dummy_open,
656 	dummy_release,
657 	NULL,
658 	dummy_start_output,
659 	dummy_stop_output,
660 	dummy_start_input,
661 	dummy_stop_input,
662 	dummy_audio_getdev,
663         dummy_set_output_volume,
664         dummy_get_output_volume,
665         dummy_set_input_volume,
666         dummy_get_input_volume,
667         dummy_set_monitor_volume,
668         dummy_get_monitor_volume,
669 	dummy_set_output_balance,
670 	dummy_get_output_balance,
671 	dummy_set_input_balance,
672 	dummy_get_input_balance,
673         dummy_set_output_channels,
674         dummy_get_output_channels,
675         dummy_set_input_channels,
676         dummy_get_input_channels,
677         dummy_set_output_precision,
678         dummy_get_output_precision,
679         dummy_set_input_precision,
680         dummy_get_input_precision,
681         dummy_set_output_port,
682         dummy_get_output_port,
683         dummy_set_input_port,
684         dummy_get_input_port,
685         dummy_set_output_encoding,
686         dummy_get_output_encoding,
687         dummy_set_input_encoding,
688         dummy_get_input_encoding,
689         dummy_set_output_rate,
690         dummy_get_output_rate,
691         dummy_set_input_rate,
692         dummy_get_input_rate,
693 	dummy_audio_getdev_sunos,
694 	dummy_get_output_ports,
695 	dummy_get_input_ports,
696 	dummy_output_muted,
697 	dummy_get_output_muted,
698 	dummy_set_output_pause,
699 	dummy_get_output_pause,
700         dummy_set_input_pause,
701 	dummy_get_input_pause,
702 	dummy_set_output_samples,
703 	dummy_get_output_samples,
704         dummy_set_input_samples,
705 	dummy_get_input_samples,
706 	dummy_set_output_error,
707 	dummy_get_output_error,
708         dummy_set_input_error,
709 	dummy_get_input_error,
710         dummy_get_formats,
711 };
712 
713 /* Attach to an dummy chip given its PROM node. */
dummy_attach(struct sparcaudio_driver * drv)714 static int __init dummy_attach(struct sparcaudio_driver *drv)
715 {
716         struct dummy_chip *dummy_chip;
717         int err;
718 
719         /* Allocate our private information structure. */
720         drv->private = kmalloc(sizeof(struct dummy_chip), GFP_KERNEL);
721         if (drv->private == NULL)
722                 return -ENOMEM;
723 
724         /* Point at the information structure and initialize it. */
725         drv->ops = &dummy_ops;
726         dummy_chip = (struct dummy_chip *) drv->private;
727 
728         /* Reset parameters. */
729         dummy_chip_reset(drv);
730 
731         /* Register ourselves with the midlevel audio driver. */
732         err = register_sparcaudio_driver(drv, 2);
733 
734         if (err < 0) {
735                 printk(KERN_ERR "dummy: unable to register\n");
736                 kfree(drv->private);
737                 return -EIO;
738         }
739 
740         dummy_chip->perchip_info.play.active =
741                 dummy_chip->perchip_info.play.pause = 0;
742 
743         dummy_chip->perchip_info.play.avail_ports = (AUDIO_HEADPHONE |
744                                                      AUDIO_SPEAKER |
745                                                      AUDIO_LINE_OUT);
746 
747         /* Announce the hardware to the user. */
748         printk(KERN_INFO "audio%d: dummy at 0x0 irq 0\n", drv->index);
749 
750         /* Success! */
751         return 0;
752 }
753 
754 /* Detach from an dummy chip given the device structure. */
dummy_detach(struct sparcaudio_driver * drv)755 static void __exit dummy_detach(struct sparcaudio_driver *drv)
756 {
757         unregister_sparcaudio_driver(drv, 2);
758         kfree(drv->private);
759 }
760 
761 /* Probe for the dummy chip and then attach the driver. */
dummy_init(void)762 static int __init dummy_init(void)
763 {
764 	num_drivers = 0;
765 
766 	/* Add support here for specifying multiple dummies to attach at once. */
767 	if (dummy_attach(&drivers[num_drivers]) == 0)
768 		num_drivers++;
769 
770 	/* Only return success if we found some dummy chips. */
771 	return (num_drivers > 0) ? 0 : -EIO;
772 }
773 
dummy_exit(void)774 static void __exit dummy_exit(void)
775 {
776         int i;
777 
778         for (i = 0; i < num_drivers; i++) {
779                 dummy_detach(&drivers[i]);
780                 num_drivers--;
781         }
782 }
783 
784 module_init(dummy_init);
785 module_exit(dummy_exit);
786 MODULE_LICENSE("GPL");
787 
788 /*
789  * Overrides for Emacs so that we follow Linus's tabbing style.
790  * Emacs will notice this stuff at the end of the file and automatically
791  * adjust the settings for this buffer only.  This must remain at the end
792  * of the file.
793  * ---------------------------------------------------------------------------
794  * Local variables:
795  * c-indent-level: 4
796  * c-brace-imaginary-offset: 0
797  * c-brace-offset: -4
798  * c-argdecl-indent: 4
799  * c-label-offset: -4
800  * c-continued-statement-offset: 4
801  * c-continued-brace-offset: 0
802  * indent-tabs-mode: nil
803  * tab-width: 8
804  * End:
805  */
806