aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/dmasound
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2007-10-18 06:06:12 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:37:26 -0400
commitfc37449f7959aeedc2d38b183468ae73c9166fb6 (patch)
tree3aaf169f3b9d9c9deb69802aa7c81354d55cf0c8 /sound/oss/dmasound
parent5b4db0c2f25925fcfc17fa7233b7b90dc023d207 (diff)
The next round of scheduled OSS code removal
This patch contains the next round of scheduled OSS code removal. Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'sound/oss/dmasound')
-rw-r--r--sound/oss/dmasound/Makefile6
-rw-r--r--sound/oss/dmasound/awacs_defs.h251
-rw-r--r--sound/oss/dmasound/dac3550a.c209
-rw-r--r--sound/oss/dmasound/dmasound.h13
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c3215
-rw-r--r--sound/oss/dmasound/dmasound_core.c287
-rw-r--r--sound/oss/dmasound/tas3001c.c849
-rw-r--r--sound/oss/dmasound/tas3001c.h64
-rw-r--r--sound/oss/dmasound/tas3001c_tables.c375
-rw-r--r--sound/oss/dmasound/tas3004.c1138
-rw-r--r--sound/oss/dmasound/tas3004.h77
-rw-r--r--sound/oss/dmasound/tas3004_tables.c301
-rw-r--r--sound/oss/dmasound/tas_common.c214
-rw-r--r--sound/oss/dmasound/tas_common.h284
-rw-r--r--sound/oss/dmasound/tas_eq_prefs.h24
-rw-r--r--sound/oss/dmasound/tas_ioctl.h23
-rw-r--r--sound/oss/dmasound/trans_16.c898
17 files changed, 0 insertions, 8228 deletions
diff --git a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile
index 4611636b1a81..3c1531652d11 100644
--- a/sound/oss/dmasound/Makefile
+++ b/sound/oss/dmasound/Makefile
@@ -2,12 +2,6 @@
2# Makefile for the DMA sound driver 2# Makefile for the DMA sound driver
3# 3#
4 4
5dmasound_pmac-y += dmasound_awacs.o \
6 trans_16.o dac3550a.o tas_common.o \
7 tas3001c.o tas3001c_tables.o \
8 tas3004.o tas3004_tables.o
9
10obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o 5obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o
11obj-$(CONFIG_DMASOUND_PMAC) += dmasound_core.o dmasound_pmac.o
12obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o 6obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o
13obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o 7obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o
diff --git a/sound/oss/dmasound/awacs_defs.h b/sound/oss/dmasound/awacs_defs.h
deleted file mode 100644
index 2194f46b046c..000000000000
--- a/sound/oss/dmasound/awacs_defs.h
+++ /dev/null
@@ -1,251 +0,0 @@
1/*********************************************************/
2/* This file was written by someone, somewhere, sometime */
3/* And is released into the Public Domain */
4/*********************************************************/
5
6#ifndef _AWACS_DEFS_H_
7#define _AWACS_DEFS_H_
8
9/*******************************/
10/* AWACs Audio Register Layout */
11/*******************************/
12
13struct awacs_regs {
14 unsigned control; /* Audio control register */
15 unsigned pad0[3];
16 unsigned codec_ctrl; /* Codec control register */
17 unsigned pad1[3];
18 unsigned codec_stat; /* Codec status register */
19 unsigned pad2[3];
20 unsigned clip_count; /* Clipping count register */
21 unsigned pad3[3];
22 unsigned byteswap; /* Data is little-endian if 1 */
23};
24
25/*******************/
26/* Audio Bit Masks */
27/*******************/
28
29/* Audio Control Reg Bit Masks */
30/* ----- ------- --- --- ----- */
31#define MASK_ISFSEL (0xf) /* Input SubFrame Select */
32#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */
33#define MASK_RATE (0x7 << 8) /* Sound Rate */
34#define MASK_CNTLERR (0x1 << 11) /* Error */
35#define MASK_PORTCHG (0x1 << 12) /* Port Change */
36#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */
37#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */
38#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */
39
40/* Audio Codec Control Reg Bit Masks */
41/* ----- ----- ------- --- --- ----- */
42#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */
43#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */
44#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */
45#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */
46
47/* Audio Codec Control Address Values / Masks */
48/* ----- ----- ------- ------- ------ - ----- */
49#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */
50#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */
51#define MASK_ADDR_GAIN MASK_ADDR0
52
53#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */
54#define MASK_ADDR_MUTE MASK_ADDR1
55#define MASK_ADDR_RATE MASK_ADDR1
56
57#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */
58#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */
59#define MASK_ADDR_VOLHD MASK_ADDR2
60
61#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */
62#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
63#define MASK_ADDR_VOLSPK MASK_ADDR4
64
65/* additional registers of screamer */
66#define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */
67#define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */
68#define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */
69
70/* Address 0 Bit Masks & Macros */
71/* ------- - --- ----- - ------ */
72#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
73#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
74#define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */
75#define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */
76
77#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
78#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */
79#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */
80#define MASK_MUX_LINE MASK_MUX_AUDIN
81
82#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
83#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
84
85#define DEF_CD_GAIN 0x00bb
86#define DEF_MIC_GAIN 0x00cc
87
88/* Address 1 Bit Masks */
89/* ------- - --- ----- */
90#define MASK_ADDR1RES1 (0x3) /* Reserved */
91#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */
92#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */
93#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */
94#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */
95#define MASK_SPKMUTE MASK_CMUTE
96#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
97#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
98#define MASK_HDMUTE MASK_AMUTE
99#define MASK_PAROUT0 (0x1 << 10) /* Parallel Output 0 */
100#define MASK_PAROUT1 (0x2 << 10) /* Parallel Output 1 */
101
102#define MASK_MIC_BOOST (0x4) /* screamer mic boost */
103
104#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
105#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
106#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */
107#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */
108#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */
109#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */
110#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */
111#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */
112
113/* Address 2 & 4 Bit Masks & Macros */
114/* ------- - - - --- ----- - ------ */
115#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */
116#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */
117#define MASK_ADDR4RES1 MASK_ADDR2RES1
118#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */
119#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */
120#define MASK_ADDR4RES2 MASK_ADDR2RES2
121
122#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT))
123#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT)
124
125/* Audio Codec Status Reg Bit Masks */
126/* ----- ----- ------ --- --- ----- */
127#define MASK_EXTEND (0x1 << 23) /* Extend */
128#define MASK_VALID (0x1 << 22) /* Valid Data? */
129#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */
130#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */
131#define MASK_ERRCODE (0xf << 16) /* Error Code */
132#define MASK_REVISION (0xf << 12) /* Revision Number */
133#define MASK_MFGID (0xf << 8) /* Mfg. ID */
134#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */
135#define MASK_INPPORT (0xf) /* Input Port */
136#define MASK_HDPCONN 8 /* headphone plugged in */
137
138/* Clipping Count Reg Bit Masks */
139/* -------- ----- --- --- ----- */
140#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */
141#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */
142
143/* DBDMA ChannelStatus Bit Masks */
144/* ----- ------------- --- ----- */
145#define MASK_CSERR (0x1 << 7) /* Error */
146#define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */
147#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */
148#define MASK_WAIT (0x1) /* Wait */
149
150/* Various Rates */
151/* ------- ----- */
152#define RATE_48000 (0x0 << 8) /* 48 kHz */
153#define RATE_44100 (0x0 << 8) /* 44.1 kHz */
154#define RATE_32000 (0x1 << 8) /* 32 kHz */
155#define RATE_29400 (0x1 << 8) /* 29.4 kHz */
156#define RATE_24000 (0x2 << 8) /* 24 kHz */
157#define RATE_22050 (0x2 << 8) /* 22.05 kHz */
158#define RATE_19200 (0x3 << 8) /* 19.2 kHz */
159#define RATE_17640 (0x3 << 8) /* 17.64 kHz */
160#define RATE_16000 (0x4 << 8) /* 16 kHz */
161#define RATE_14700 (0x4 << 8) /* 14.7 kHz */
162#define RATE_12000 (0x5 << 8) /* 12 kHz */
163#define RATE_11025 (0x5 << 8) /* 11.025 kHz */
164#define RATE_9600 (0x6 << 8) /* 9.6 kHz */
165#define RATE_8820 (0x6 << 8) /* 8.82 kHz */
166#define RATE_8000 (0x7 << 8) /* 8 kHz */
167#define RATE_7350 (0x7 << 8) /* 7.35 kHz */
168
169#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
170
171/*******************/
172/* Burgundy values */
173/*******************/
174
175#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
176#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
177
178#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
179#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
180#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
181#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
182
183#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
184#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
185#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
186#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
187
188#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
189#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
190
191#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
192
193#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
194
195#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
196#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
197#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
198
199#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
200#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
201#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
202#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
203
204#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
205#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
206#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
207#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
208
209
210/* These are all default values for the burgundy */
211#define DEF_BURGUNDY_INPSEL21 (0xAA)
212#define DEF_BURGUNDY_INPSEL3 (0x0A)
213
214#define DEF_BURGUNDY_GAINCD (0x33)
215#define DEF_BURGUNDY_GAINLINE (0x44)
216#define DEF_BURGUNDY_GAINMIC (0x44)
217#define DEF_BURGUNDY_GAINMODEM (0x06)
218
219/* Remember: lowest volume here is 0x9b */
220#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
221#define DEF_BURGUNDY_VOLLINE (0x00000000)
222#define DEF_BURGUNDY_VOLMIC (0x00000000)
223#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
224
225#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
226#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
227
228#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
229
230#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
231
232#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
233#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
234#define DEF_BURGUNDY_ATTENHP (0xCC)
235
236/*********************/
237/* i2s layout values */
238/*********************/
239
240#define I2S_REG_INT_CTL 0x00
241#define I2S_REG_SERIAL_FORMAT 0x10
242#define I2S_REG_CODEC_MSG_OUT 0x20
243#define I2S_REG_CODEC_MSG_IN 0x30
244#define I2S_REG_FRAME_COUNT 0x40
245#define I2S_REG_FRAME_MATCH 0x50
246#define I2S_REG_DATAWORD_SIZES 0x60
247#define I2S_REG_PEAKLEVEL_SEL 0x70
248#define I2S_REG_PEAKLEVEL_IN0 0x80
249#define I2S_REG_PEAKLEVEL_IN1 0x90
250
251#endif /* _AWACS_DEFS_H_ */
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c
deleted file mode 100644
index 0f0d03a55dab..000000000000
--- a/sound/oss/dmasound/dac3550a.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/*
2 * Driver for the i2c/i2s based DAC3550a sound chip used
3 * on some Apple iBooks. Also known as "DACA".
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file COPYING in the main directory of this archive
7 * for more details.
8 */
9
10#include <linux/module.h>
11#include <linux/slab.h>
12#include <linux/delay.h>
13#include <linux/proc_fs.h>
14#include <linux/ioport.h>
15#include <linux/sysctl.h>
16#include <linux/types.h>
17#include <linux/i2c.h>
18#include <linux/init.h>
19#include <asm/uaccess.h>
20#include <asm/errno.h>
21#include <asm/io.h>
22
23#include "dmasound.h"
24
25/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
26 * control code, as well as info derived from the AppleDACAAudio driver
27 * from Darwin CVS (main thing I derived being register numbers and
28 * values, as well as when to make the calls). */
29
30#define I2C_DRIVERID_DACA (0xFDCB)
31
32#define DACA_VERSION "0.1"
33#define DACA_DATE "20010930"
34
35static int cur_left_vol;
36static int cur_right_vol;
37static struct i2c_client *daca_client;
38
39static int daca_attach_adapter(struct i2c_adapter *adapter);
40static int daca_detect_client(struct i2c_adapter *adapter, int address);
41static int daca_detach_client(struct i2c_client *client);
42
43struct i2c_driver daca_driver = {
44 .driver = {
45 .name = "DAC3550A driver V " DACA_VERSION,
46 },
47 .id = I2C_DRIVERID_DACA,
48 .attach_adapter = daca_attach_adapter,
49 .detach_client = daca_detach_client,
50};
51
52#define VOL_MAX ((1<<20) - 1)
53
54void daca_get_volume(uint * left_vol, uint *right_vol)
55{
56 *left_vol = cur_left_vol >> 5;
57 *right_vol = cur_right_vol >> 5;
58}
59
60int daca_set_volume(uint left_vol, uint right_vol)
61{
62 unsigned short voldata;
63
64 if (!daca_client)
65 return -1;
66
67 /* Derived from experience, not from any specific values */
68 left_vol <<= 5;
69 right_vol <<= 5;
70
71 if (left_vol > VOL_MAX)
72 left_vol = VOL_MAX;
73 if (right_vol > VOL_MAX)
74 right_vol = VOL_MAX;
75
76 voldata = ((left_vol >> 14) & 0x3f) << 8;
77 voldata |= (right_vol >> 14) & 0x3f;
78
79 if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
80 printk("daca: failed to set volume \n");
81 return -1;
82 }
83
84 cur_left_vol = left_vol;
85 cur_right_vol = right_vol;
86
87 return 0;
88}
89
90int daca_leave_sleep(void)
91{
92 if (!daca_client)
93 return -1;
94
95 /* Do a short sleep, just to make sure I2C bus is awake and paying
96 * attention to us
97 */
98 msleep(20);
99 /* Write the sample rate reg the value it needs */
100 i2c_smbus_write_byte_data(daca_client, 1, 8);
101 daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
102 /* Another short delay, just to make sure the other I2C bus writes
103 * have taken...
104 */
105 msleep(20);
106 /* Write the global config reg - invert right power amp,
107 * DAC on, use 5-volt mode */
108 i2c_smbus_write_byte_data(daca_client, 3, 0x45);
109
110 return 0;
111}
112
113int daca_enter_sleep(void)
114{
115 if (!daca_client)
116 return -1;
117
118 i2c_smbus_write_byte_data(daca_client, 1, 8);
119 daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
120
121 /* Write the global config reg - invert right power amp,
122 * DAC on, enter low-power mode, use 5-volt mode
123 */
124 i2c_smbus_write_byte_data(daca_client, 3, 0x65);
125
126 return 0;
127}
128
129static int daca_attach_adapter(struct i2c_adapter *adapter)
130{
131 if (!strncmp(adapter->name, "mac-io", 6))
132 daca_detect_client(adapter, 0x4d);
133 return 0;
134}
135
136static int daca_init_client(struct i2c_client * new_client)
137{
138 /*
139 * Probe is not working with the current i2c-keywest
140 * driver. We try to use addr 0x4d on each adapters
141 * instead, by setting the format register.
142 *
143 * FIXME: I'm sure that can be obtained from the
144 * device-tree. --BenH.
145 */
146
147 /* Write the global config reg - invert right power amp,
148 * DAC on, use 5-volt mode
149 */
150 if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
151 return -1;
152
153 i2c_smbus_write_byte_data(new_client, 1, 8);
154 daca_client = new_client;
155 daca_set_volume(15000, 15000);
156
157 return 0;
158}
159
160static int daca_detect_client(struct i2c_adapter *adapter, int address)
161{
162 const char *client_name = "DAC 3550A Digital Equalizer";
163 struct i2c_client *new_client;
164 int rc = -ENODEV;
165
166 new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
167 if (!new_client)
168 return -ENOMEM;
169
170 new_client->addr = address;
171 new_client->adapter = adapter;
172 new_client->driver = &daca_driver;
173 new_client->flags = 0;
174 strcpy(new_client->name, client_name);
175
176 if (daca_init_client(new_client))
177 goto bail;
178
179 /* Tell the i2c layer a new client has arrived */
180 if (i2c_attach_client(new_client))
181 goto bail;
182
183 return 0;
184 bail:
185 kfree(new_client);
186 return rc;
187}
188
189
190static int daca_detach_client(struct i2c_client *client)
191{
192 if (client == daca_client)
193 daca_client = NULL;
194
195 i2c_detach_client(client);
196 kfree(client);
197 return 0;
198}
199
200void daca_cleanup(void)
201{
202 i2c_del_driver(&daca_driver);
203}
204
205int daca_init(void)
206{
207 printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
208 return i2c_add_driver(&daca_driver);
209}
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 25dd5a318eb4..d978b0096564 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -59,7 +59,6 @@ static inline int ioctl_return(int __user *addr, int value)
59 */ 59 */
60 60
61#undef HAS_8BIT_TABLES 61#undef HAS_8BIT_TABLES
62#undef HAS_RECORD
63 62
64#if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\ 63#if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
65 defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\ 64 defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
@@ -83,10 +82,6 @@ static inline int ioctl_return(int __user *addr, int value)
83#define DEFAULT_N_BUFFERS 4 82#define DEFAULT_N_BUFFERS 4
84#define DEFAULT_BUFF_SIZE (1<<15) 83#define DEFAULT_BUFF_SIZE (1<<15)
85 84
86#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE)
87#define HAS_RECORD
88#endif
89
90 /* 85 /*
91 * Initialization 86 * Initialization
92 */ 87 */
@@ -168,9 +163,6 @@ struct sound_settings {
168 SETTINGS soft; /* software settings */ 163 SETTINGS soft; /* software settings */
169 SETTINGS dsp; /* /dev/dsp default settings */ 164 SETTINGS dsp; /* /dev/dsp default settings */
170 TRANS *trans_write; /* supported translations */ 165 TRANS *trans_write; /* supported translations */
171#ifdef HAS_RECORD
172 TRANS *trans_read; /* supported translations */
173#endif
174 int volume_left; /* volume (range is machine dependent) */ 166 int volume_left; /* volume (range is machine dependent) */
175 int volume_right; 167 int volume_right;
176 int bass; /* tone (range is machine dependent) */ 168 int bass; /* tone (range is machine dependent) */
@@ -253,11 +245,6 @@ struct sound_queue {
253extern struct sound_queue dmasound_write_sq; 245extern struct sound_queue dmasound_write_sq;
254#define write_sq dmasound_write_sq 246#define write_sq dmasound_write_sq
255 247
256#ifdef HAS_RECORD
257extern struct sound_queue dmasound_read_sq;
258#define read_sq dmasound_read_sq
259#endif
260
261extern int dmasound_catchRadius; 248extern int dmasound_catchRadius;
262#define catchRadius dmasound_catchRadius 249#define catchRadius dmasound_catchRadius
263 250
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
deleted file mode 100644
index 8f6388004f44..000000000000
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ /dev/null
@@ -1,3215 +0,0 @@
1/*
2 * linux/sound/oss/dmasound/dmasound_awacs.c
3 *
4 * PowerMac `AWACS' and `Burgundy' DMA Sound Driver
5 * with some limited support for DACA & Tumbler
6 *
7 * See linux/sound/oss/dmasound/dmasound_core.c for copyright and
8 * history prior to 2001/01/26.
9 *
10 * 26/01/2001 ed 0.1 Iain Sandoe
11 * - added version info.
12 * - moved dbdma command buffer allocation to PMacXXXSqSetup()
13 * - fixed up beep dbdma cmd buffers
14 *
15 * 08/02/2001 [0.2]
16 * - make SNDCTL_DSP_GETFMTS return the correct info for the h/w
17 * - move soft format translations to a separate file
18 * - [0.3] make SNDCTL_DSP_GETCAPS return correct info.
19 * - [0.4] more informative machine name strings.
20 * - [0.5]
21 * - record changes.
22 * - made the default_hard/soft entries.
23 * 04/04/2001 [0.6]
24 * - minor correction to bit assignments in awacs_defs.h
25 * - incorporate mixer changes from 2.2.x back-port.
26 * - take out passthru as a rec input (it isn't).
27 * - make Input Gain slider work the 'right way up'.
28 * - try to make the mixer sliders more logical - so now the
29 * input selectors are just two-state (>50% == ON) and the
30 * Input Gain slider handles the rest of the gain issues.
31 * - try to pick slider representations that most closely match
32 * the actual use - e.g. IGain for input gain...
33 * - first stab at over/under-run detection.
34 * - minor cosmetic changes to IRQ identification.
35 * - fix bug where rates > max would be reported as supported.
36 * - first stab at over/under-run detection.
37 * - make use of i2c for mixer settings conditional on perch
38 * rather than cuda (some machines without perch have cuda).
39 * - fix bug where TX stops when dbdma status comes up "DEAD"
40 * so far only reported on PowerComputing clones ... but.
41 * - put in AWACS/Screamer register write timeouts.
42 * - part way to partitioning the init() stuff
43 * - first pass at 'tumbler' stuff (not support - just an attempt
44 * to allow the driver to load on new G4s).
45 * 01/02/2002 [0.7] - BenH
46 * - all sort of minor bits went in since the latest update, I
47 * bumped the version number for that reason
48 *
49 * 07/26/2002 [0.8] - BenH
50 * - More minor bits since last changelog (I should be more careful
51 * with those)
52 * - Support for snapper & better tumbler integration by Toby Sargeant
53 * - Headphone detect for scremer by Julien Blache
54 * - More tumbler fixed by Andreas Schwab
55 * 11/29/2003 [0.8.1] - Renzo Davoli (King Enzo)
56 * - Support for Snapper line in
57 * - snapper input resampling (for rates < 44100)
58 * - software line gain control
59 */
60
61/* GENERAL FIXME/TODO: check that the assumptions about what is written to
62 mac-io is valid for DACA & Tumbler.
63
64 This driver is in bad need of a rewrite. The dbdma code has to be split,
65 some proper device-tree parsing code has to be written, etc...
66*/
67
68#include <linux/types.h>
69#include <linux/module.h>
70#include <linux/slab.h>
71#include <linux/init.h>
72#include <linux/delay.h>
73#include <linux/soundcard.h>
74#include <linux/adb.h>
75#include <linux/nvram.h>
76#include <linux/tty.h>
77#include <linux/vt_kern.h>
78#include <linux/spinlock.h>
79#include <linux/kmod.h>
80#include <linux/interrupt.h>
81#include <linux/input.h>
82#include <linux/mutex.h>
83#ifdef CONFIG_ADB_CUDA
84#include <linux/cuda.h>
85#endif
86#ifdef CONFIG_ADB_PMU
87#include <linux/pmu.h>
88#endif
89
90#include <asm/uaccess.h>
91#include <asm/prom.h>
92#include <asm/machdep.h>
93#include <asm/io.h>
94#include <asm/dbdma.h>
95#include <asm/pmac_feature.h>
96#include <asm/irq.h>
97#include <asm/nvram.h>
98
99#include "awacs_defs.h"
100#include "dmasound.h"
101#include "tas3001c.h"
102#include "tas3004.h"
103#include "tas_common.h"
104
105#define DMASOUND_AWACS_REVISION 0
106#define DMASOUND_AWACS_EDITION 7
107
108#define AWACS_SNAPPER 110 /* fake revision # for snapper */
109#define AWACS_BURGUNDY 100 /* fake revision # for burgundy */
110#define AWACS_TUMBLER 90 /* fake revision # for tumbler */
111#define AWACS_DACA 80 /* fake revision # for daca (ibook) */
112#define AWACS_AWACS 2 /* holding revision for AWACS */
113#define AWACS_SCREAMER 3 /* holding revision for Screamer */
114/*
115 * Interrupt numbers and addresses, & info obtained from the device tree.
116 */
117static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
118static volatile struct awacs_regs __iomem *awacs;
119static volatile u32 __iomem *i2s;
120static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma;
121static int awacs_rate_index;
122static int awacs_subframe;
123static struct device_node* awacs_node;
124static struct device_node* i2s_node;
125static struct resource awacs_rsrc[3];
126
127static char awacs_name[64];
128static int awacs_revision;
129static int awacs_sleeping;
130static DEFINE_MUTEX(dmasound_mutex);
131
132static int sound_device_id; /* exists after iMac revA */
133static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */
134
135/* model info */
136/* To be replaced with better interaction with pmac_feature.c */
137static int is_pbook_3X00;
138static int is_pbook_g3;
139
140/* expansion info */
141static int has_perch;
142static int has_ziva;
143
144/* for earlier powerbooks which need fiddling with mac-io to enable
145 * cd etc.
146*/
147static unsigned char __iomem *latch_base;
148static unsigned char __iomem *macio_base;
149
150/*
151 * Space for the DBDMA command blocks.
152 */
153static void *awacs_tx_cmd_space;
154static volatile struct dbdma_cmd *awacs_tx_cmds;
155static int number_of_tx_cmd_buffers;
156
157static void *awacs_rx_cmd_space;
158static volatile struct dbdma_cmd *awacs_rx_cmds;
159static int number_of_rx_cmd_buffers;
160
161/*
162 * Cached values of AWACS registers (we can't read them).
163 * Except on the burgundy (and screamer). XXX
164 */
165
166int awacs_reg[8];
167int awacs_reg1_save;
168
169/* tracking values for the mixer contents
170*/
171
172static int spk_vol;
173static int line_vol;
174static int passthru_vol;
175
176static int ip_gain; /* mic preamp settings */
177static int rec_lev = 0x4545 ; /* default CD gain 69 % */
178static int mic_lev;
179static int cd_lev = 0x6363 ; /* 99 % */
180static int line_lev;
181
182static int hdp_connected;
183
184/*
185 * Stuff for outputting a beep. The values range from -327 to +327
186 * so we can multiply by an amplitude in the range 0..100 to get a
187 * signed short value to put in the output buffer.
188 */
189static short beep_wform[256] = {
190 0, 40, 79, 117, 153, 187, 218, 245,
191 269, 288, 304, 316, 323, 327, 327, 324,
192 318, 310, 299, 288, 275, 262, 249, 236,
193 224, 213, 204, 196, 190, 186, 183, 182,
194 182, 183, 186, 189, 192, 196, 200, 203,
195 206, 208, 209, 209, 209, 207, 204, 201,
196 197, 193, 188, 183, 179, 174, 170, 166,
197 163, 161, 160, 159, 159, 160, 161, 162,
198 164, 166, 168, 169, 171, 171, 171, 170,
199 169, 167, 163, 159, 155, 150, 144, 139,
200 133, 128, 122, 117, 113, 110, 107, 105,
201 103, 103, 103, 103, 104, 104, 105, 105,
202 105, 103, 101, 97, 92, 86, 78, 68,
203 58, 45, 32, 18, 3, -11, -26, -41,
204 -55, -68, -79, -88, -95, -100, -102, -102,
205 -99, -93, -85, -75, -62, -48, -33, -16,
206 0, 16, 33, 48, 62, 75, 85, 93,
207 99, 102, 102, 100, 95, 88, 79, 68,
208 55, 41, 26, 11, -3, -18, -32, -45,
209 -58, -68, -78, -86, -92, -97, -101, -103,
210 -105, -105, -105, -104, -104, -103, -103, -103,
211 -103, -105, -107, -110, -113, -117, -122, -128,
212 -133, -139, -144, -150, -155, -159, -163, -167,
213 -169, -170, -171, -171, -171, -169, -168, -166,
214 -164, -162, -161, -160, -159, -159, -160, -161,
215 -163, -166, -170, -174, -179, -183, -188, -193,
216 -197, -201, -204, -207, -209, -209, -209, -208,
217 -206, -203, -200, -196, -192, -189, -186, -183,
218 -182, -182, -183, -186, -190, -196, -204, -213,
219 -224, -236, -249, -262, -275, -288, -299, -310,
220 -318, -324, -327, -327, -323, -316, -304, -288,
221 -269, -245, -218, -187, -153, -117, -79, -40,
222};
223
224/* beep support */
225#define BEEP_SRATE 22050 /* 22050 Hz sample rate */
226#define BEEP_BUFLEN 512
227#define BEEP_VOLUME 15 /* 0 - 100 */
228
229static int beep_vol = BEEP_VOLUME;
230static int beep_playing;
231static int awacs_beep_state;
232static short *beep_buf;
233static void *beep_dbdma_cmd_space;
234static volatile struct dbdma_cmd *beep_dbdma_cmd;
235
236/* Burgundy functions */
237static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
238static unsigned awacs_burgundy_rcw(unsigned addr);
239static void awacs_burgundy_write_volume(unsigned address, int volume);
240static int awacs_burgundy_read_volume(unsigned address);
241static void awacs_burgundy_write_mvolume(unsigned address, int volume);
242static int awacs_burgundy_read_mvolume(unsigned address);
243
244/* we will allocate a single 'emergency' dbdma cmd block to use if the
245 tx status comes up "DEAD". This happens on some PowerComputing Pmac
246 clones, either owing to a bug in dbdma or some interaction between
247 IDE and sound. However, this measure would deal with DEAD status if
248 if appeared elsewhere.
249
250 for the sake of memory efficiency we'll allocate this cmd as part of
251 the beep cmd stuff.
252*/
253
254static volatile struct dbdma_cmd *emergency_dbdma_cmd;
255
256#ifdef CONFIG_PM
257/*
258 * Stuff for restoring after a sleep.
259 */
260static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when);
261struct pmu_sleep_notifier awacs_sleep_notifier = {
262 awacs_sleep_notify, SLEEP_LEVEL_SOUND,
263};
264#endif /* CONFIG_PM */
265
266/* for (soft) sample rate translations */
267int expand_bal; /* Balance factor for expanding (not volume!) */
268int expand_read_bal; /* Balance factor for expanding reads (not volume!) */
269
270/*** Low level stuff *********************************************************/
271
272static void *PMacAlloc(unsigned int size, gfp_t flags);
273static void PMacFree(void *ptr, unsigned int size);
274static int PMacIrqInit(void);
275#ifdef MODULE
276static void PMacIrqCleanup(void);
277#endif
278static void PMacSilence(void);
279static void PMacInit(void);
280static int PMacSetFormat(int format);
281static int PMacSetVolume(int volume);
282static void PMacPlay(void);
283static void PMacRecord(void);
284static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid);
285static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid);
286static irqreturn_t pmac_awacs_intr(int irq, void *devid);
287static void awacs_write(int val);
288static int awacs_get_volume(int reg, int lshift);
289static int awacs_volume_setter(int volume, int n, int mute, int lshift);
290
291
292/*** Mid level stuff **********************************************************/
293
294static int PMacMixerIoctl(u_int cmd, u_long arg);
295static int PMacWriteSqSetup(void);
296static int PMacReadSqSetup(void);
297static void PMacAbortRead(void);
298
299extern TRANS transAwacsNormal ;
300extern TRANS transAwacsExpand ;
301extern TRANS transAwacsNormalRead ;
302extern TRANS transAwacsExpandRead ;
303
304extern int daca_init(void);
305extern void daca_cleanup(void);
306extern int daca_set_volume(uint left_vol, uint right_vol);
307extern void daca_get_volume(uint * left_vol, uint *right_vol);
308extern int daca_enter_sleep(void);
309extern int daca_leave_sleep(void);
310
311#define TRY_LOCK() \
312 if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \
313 return rc;
314#define LOCK() mutex_lock(&dmasound_mutex);
315
316#define UNLOCK() mutex_unlock(&dmasound_mutex);
317
318/* We use different versions that the ones provided in dmasound.h
319 *
320 * FIXME: Use different names ;)
321 */
322#undef IOCTL_IN
323#undef IOCTL_OUT
324
325#define IOCTL_IN(arg, ret) \
326 rc = get_user(ret, (int __user *)(arg)); \
327 if (rc) break;
328#define IOCTL_OUT(arg, ret) \
329 ioctl_return2((int __user *)(arg), ret)
330
331static inline int ioctl_return2(int __user *addr, int value)
332{
333 return value < 0 ? value : put_user(value, addr);
334}
335
336
337/*** AE - TUMBLER / SNAPPER START ************************************************/
338
339
340int gpio_audio_reset, gpio_audio_reset_pol;
341int gpio_amp_mute, gpio_amp_mute_pol;
342int gpio_headphone_mute, gpio_headphone_mute_pol;
343int gpio_headphone_detect, gpio_headphone_detect_pol;
344int gpio_headphone_irq;
345
346int
347setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol)
348{
349 struct device_node *gpiop;
350 struct device_node *np;
351 const u32* pp;
352 int ret = -ENODEV;
353
354 gpiop = of_find_node_by_name(NULL, "gpio");
355 if (!gpiop)
356 goto done;
357
358 np = of_get_next_child(gpiop, NULL);
359 while(np != 0) {
360 if (name) {
361 const char *property =
362 of_get_property(np,"audio-gpio",NULL);
363 if (property != 0 && strcmp(property,name) == 0)
364 break;
365 } else if (compatible && of_device_is_compatible(np, compatible))
366 break;
367 np = of_get_next_child(gpiop, np);
368 }
369 if (!np)
370 goto done;
371 pp = of_get_property(np, "AAPL,address", NULL);
372 if (!pp)
373 goto done;
374 *gpio_addr = (*pp) & 0x0000ffff;
375 pp = of_get_property(np, "audio-gpio-active-state", NULL);
376 if (pp)
377 *gpio_pol = *pp;
378 else
379 *gpio_pol = 1;
380 ret = irq_of_parse_and_map(np, 0);
381done:
382 of_node_put(np);
383 of_node_put(gpiop);
384 return ret;
385}
386
387static inline void
388write_audio_gpio(int gpio_addr, int data)
389{
390 if (!gpio_addr)
391 return;
392 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04);
393}
394
395static inline int
396read_audio_gpio(int gpio_addr)
397{
398 if (!gpio_addr)
399 return 0;
400 return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
401}
402
403/*
404 * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
405 */
406static irqreturn_t
407headphone_intr(int irq, void *devid)
408{
409 unsigned long flags;
410
411 spin_lock_irqsave(&dmasound.lock, flags);
412 if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
413 printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
414 write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
415 write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
416 tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
417 } else {
418 printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
419 write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
420 write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
421 tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
422 }
423 spin_unlock_irqrestore(&dmasound.lock, flags);
424 return IRQ_HANDLED;
425}
426
427
428/* Initialize tumbler */
429
430static int
431tas_dmasound_init(void)
432{
433 setup_audio_gpio(
434 "audio-hw-reset",
435 NULL,
436 &gpio_audio_reset,
437 &gpio_audio_reset_pol);
438 setup_audio_gpio(
439 "amp-mute",
440 NULL,
441 &gpio_amp_mute,
442 &gpio_amp_mute_pol);
443 setup_audio_gpio("headphone-mute",
444 NULL,
445 &gpio_headphone_mute,
446 &gpio_headphone_mute_pol);
447 gpio_headphone_irq = setup_audio_gpio(
448 "headphone-detect",
449 NULL,
450 &gpio_headphone_detect,
451 &gpio_headphone_detect_pol);
452 /* Fix some broken OF entries in desktop machines */
453 if (!gpio_headphone_irq)
454 gpio_headphone_irq = setup_audio_gpio(
455 NULL,
456 "keywest-gpio15",
457 &gpio_headphone_detect,
458 &gpio_headphone_detect_pol);
459
460 write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
461 msleep(100);
462 write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
463 msleep(100);
464 if (gpio_headphone_irq) {
465 if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) {
466 printk(KERN_ERR "tumbler: Can't request headphone interrupt\n");
467 gpio_headphone_irq = 0;
468 } else {
469 u8 val;
470 /* Activate headphone status interrupts */
471 val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0);
472 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80);
473 /* Trigger it */
474 headphone_intr(0, NULL);
475 }
476 }
477 if (!gpio_headphone_irq) {
478 /* Some machine enter this case ? */
479 printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n");
480 write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
481 write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
482 }
483 return 0;
484}
485
486
487static int
488tas_dmasound_cleanup(void)
489{
490 if (gpio_headphone_irq)
491 free_irq(gpio_headphone_irq, NULL);
492 return 0;
493}
494
495/* We don't support 48k yet */
496static int tas_freqs[1] = { 44100 } ;
497static int tas_freqs_ok[1] = { 1 } ;
498
499/* don't know what to do really - just have to leave it where
500 * OF left things
501*/
502
503static int
504tas_set_frame_rate(void)
505{
506 if (i2s) {
507 out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
508 out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
509 }
510 dmasound.hard.speed = 44100 ;
511 awacs_rate_index = 0 ;
512 return 44100 ;
513}
514
515static int
516tas_mixer_ioctl(u_int cmd, u_long arg)
517{
518 int __user *argp = (int __user *)arg;
519 int data;
520 int rc;
521
522 rc=tas_device_ioctl(cmd, arg);
523 if (rc != -EINVAL) {
524 return rc;
525 }
526
527 if ((cmd & ~0xff) == MIXER_WRITE(0) &&
528 tas_supported_mixers() & (1<<(cmd & 0xff))) {
529 rc = get_user(data, argp);
530 if (rc<0) return rc;
531 tas_set_mixer_level(cmd & 0xff, data);
532 tas_get_mixer_level(cmd & 0xff, &data);
533 return ioctl_return2(argp, data);
534 }
535 if ((cmd & ~0xff) == MIXER_READ(0) &&
536 tas_supported_mixers() & (1<<(cmd & 0xff))) {
537 tas_get_mixer_level(cmd & 0xff, &data);
538 return ioctl_return2(argp, data);
539 }
540
541 switch(cmd) {
542 case SOUND_MIXER_READ_DEVMASK:
543 data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
544 rc = IOCTL_OUT(arg, data);
545 break;
546 case SOUND_MIXER_READ_STEREODEVS:
547 data = tas_stereo_mixers();
548 rc = IOCTL_OUT(arg, data);
549 break;
550 case SOUND_MIXER_READ_CAPS:
551 rc = IOCTL_OUT(arg, 0);
552 break;
553 case SOUND_MIXER_READ_RECMASK:
554 // XXX FIXME: find a way to check what is really available */
555 data = SOUND_MASK_LINE | SOUND_MASK_MIC;
556 rc = IOCTL_OUT(arg, data);
557 break;
558 case SOUND_MIXER_READ_RECSRC:
559 if (awacs_reg[0] & MASK_MUX_AUDIN)
560 data |= SOUND_MASK_LINE;
561 if (awacs_reg[0] & MASK_MUX_MIC)
562 data |= SOUND_MASK_MIC;
563 rc = IOCTL_OUT(arg, data);
564 break;
565 case SOUND_MIXER_WRITE_RECSRC:
566 IOCTL_IN(arg, data);
567 data =0;
568 rc = IOCTL_OUT(arg, data);
569 break;
570 case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */
571 IOCTL_IN(arg, data);
572 beep_vol = data & 0xff;
573 /* fall through */
574 case SOUND_MIXER_READ_SPEAKER:
575 rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
576 break;
577 case SOUND_MIXER_OUTMASK:
578 case SOUND_MIXER_OUTSRC:
579 default:
580 rc = -EINVAL;
581 }
582
583 return rc;
584}
585
586static void __init
587tas_init_frame_rates(const unsigned int *prop, unsigned int l)
588{
589 int i ;
590 if (prop) {
591 for (i=0; i<1; i++)
592 tas_freqs_ok[i] = 0;
593 for (l /= sizeof(int); l > 0; --l) {
594 unsigned int r = *prop++;
595 /* Apple 'Fixed' format */
596 if (r >= 0x10000)
597 r >>= 16;
598 for (i = 0; i < 1; ++i) {
599 if (r == tas_freqs[i]) {
600 tas_freqs_ok[i] = 1;
601 break;
602 }
603 }
604 }
605 }
606 /* else we assume that all the rates are available */
607}
608
609
610/*** AE - TUMBLER / SNAPPER END ************************************************/
611
612
613
614/*** Low level stuff *********************************************************/
615
616/*
617 * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
618 */
619static void *PMacAlloc(unsigned int size, gfp_t flags)
620{
621 return kmalloc(size, flags);
622}
623
624static void PMacFree(void *ptr, unsigned int size)
625{
626 kfree(ptr);
627}
628
629static int __init PMacIrqInit(void)
630{
631 if (awacs)
632 if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL))
633 return 0;
634 if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL)
635 || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL))
636 return 0;
637 return 1;
638}
639
640#ifdef MODULE
641static void PMacIrqCleanup(void)
642{
643 /* turn off input & output dma */
644 DBDMA_DO_STOP(awacs_txdma);
645 DBDMA_DO_STOP(awacs_rxdma);
646
647 if (awacs)
648 /* disable interrupts from awacs interface */
649 out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
650
651 /* Switch off the sound clock */
652 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
653 /* Make sure proper bits are set on pismo & tipb */
654 if ((machine_is_compatible("PowerBook3,1") ||
655 machine_is_compatible("PowerBook3,2")) && awacs) {
656 awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
657 awacs_write(MASK_ADDR1 | awacs_reg[1]);
658 msleep(200);
659 }
660 if (awacs)
661 free_irq(awacs_irq, NULL);
662 free_irq(awacs_tx_irq, NULL);
663 free_irq(awacs_rx_irq, NULL);
664
665 if (awacs)
666 iounmap(awacs);
667 if (i2s)
668 iounmap(i2s);
669 iounmap(awacs_txdma);
670 iounmap(awacs_rxdma);
671
672 release_mem_region(awacs_rsrc[0].start,
673 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
674 release_mem_region(awacs_rsrc[1].start,
675 awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
676 release_mem_region(awacs_rsrc[2].start,
677 awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
678
679 kfree(awacs_tx_cmd_space);
680 kfree(awacs_rx_cmd_space);
681 kfree(beep_dbdma_cmd_space);
682 kfree(beep_buf);
683#ifdef CONFIG_PM
684 pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
685#endif
686}
687#endif /* MODULE */
688
689static void PMacSilence(void)
690{
691 /* turn off output dma */
692 DBDMA_DO_STOP(awacs_txdma);
693}
694
695/* don't know what to do really - just have to leave it where
696 * OF left things
697*/
698
699static int daca_set_frame_rate(void)
700{
701 if (i2s) {
702 out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
703 out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
704 }
705 dmasound.hard.speed = 44100 ;
706 awacs_rate_index = 0 ;
707 return 44100 ;
708}
709
710static int awacs_freqs[8] = {
711 44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
712};
713static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
714
715static int
716awacs_set_frame_rate(int desired, int catch_r)
717{
718 int tolerance, i = 8 ;
719 /*
720 * If we have a sample rate which is within catchRadius percent
721 * of the requested value, we don't have to expand the samples.
722 * Otherwise choose the next higher rate.
723 * N.B.: burgundy awacs only works at 44100 Hz.
724 */
725 do {
726 tolerance = catch_r * awacs_freqs[--i] / 100;
727 if (awacs_freqs_ok[i]
728 && dmasound.soft.speed <= awacs_freqs[i] + tolerance)
729 break;
730 } while (i > 0);
731 dmasound.hard.speed = awacs_freqs[i];
732 awacs_rate_index = i;
733
734 out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 );
735 awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3);
736 awacs_write(awacs_reg[1] | MASK_ADDR1);
737 return dmasound.hard.speed;
738}
739
740static int
741burgundy_set_frame_rate(void)
742{
743 awacs_rate_index = 0 ;
744 awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
745 /* XXX disable error interrupt on burgundy for now */
746 out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE);
747 return 44100 ;
748}
749
750static int
751set_frame_rate(int desired, int catch_r)
752{
753 switch (awacs_revision) {
754 case AWACS_BURGUNDY:
755 dmasound.hard.speed = burgundy_set_frame_rate();
756 break ;
757 case AWACS_TUMBLER:
758 case AWACS_SNAPPER:
759 dmasound.hard.speed = tas_set_frame_rate();
760 break ;
761 case AWACS_DACA:
762 dmasound.hard.speed =
763 daca_set_frame_rate();
764 break ;
765 default:
766 dmasound.hard.speed = awacs_set_frame_rate(desired,
767 catch_r);
768 break ;
769 }
770 return dmasound.hard.speed ;
771}
772
773static void
774awacs_recalibrate(void)
775{
776 /* Sorry for the horrible delays... I hope to get that improved
777 * by making the whole PM process asynchronous in a future version
778 */
779 msleep(750);
780 awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE;
781 awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1);
782 msleep(1000);
783 awacs_write(awacs_reg[1] | MASK_ADDR1);
784}
785
786static void PMacInit(void)
787{
788 int tolerance;
789
790 switch (dmasound.soft.format) {
791 case AFMT_S16_LE:
792 case AFMT_U16_LE:
793 if (hw_can_byteswap)
794 dmasound.hard.format = AFMT_S16_LE;
795 else
796 dmasound.hard.format = AFMT_S16_BE;
797 break;
798 default:
799 dmasound.hard.format = AFMT_S16_BE;
800 break;
801 }
802 dmasound.hard.stereo = 1;
803 dmasound.hard.size = 16;
804
805 /* set dmasound.hard.speed - on the basis of what we want (soft)
806 * and the tolerance we'll allow.
807 */
808 set_frame_rate(dmasound.soft.speed, catchRadius) ;
809
810 tolerance = (catchRadius * dmasound.hard.speed) / 100;
811 if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) {
812 dmasound.trans_write = &transAwacsNormal;
813 dmasound.trans_read = &transAwacsNormalRead;
814 } else {
815 dmasound.trans_write = &transAwacsExpand;
816 dmasound.trans_read = &transAwacsExpandRead;
817 }
818
819 if (awacs) {
820 if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
821 out_le32(&awacs->byteswap, BS_VAL);
822 else
823 out_le32(&awacs->byteswap, 0);
824 }
825
826 expand_bal = -dmasound.soft.speed;
827 expand_read_bal = -dmasound.soft.speed;
828}
829
830static int PMacSetFormat(int format)
831{
832 int size;
833 int req_format = format;
834
835 switch (format) {
836 case AFMT_QUERY:
837 return dmasound.soft.format;
838 case AFMT_MU_LAW:
839 case AFMT_A_LAW:
840 case AFMT_U8:
841 case AFMT_S8:
842 size = 8;
843 break;
844 case AFMT_S16_LE:
845 if(!hw_can_byteswap)
846 format = AFMT_S16_BE;
847 case AFMT_S16_BE:
848 size = 16;
849 break;
850 case AFMT_U16_LE:
851 if(!hw_can_byteswap)
852 format = AFMT_U16_BE;
853 case AFMT_U16_BE:
854 size = 16;
855 break;
856 default: /* :-) */
857 printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
858 format);
859 size = 8;
860 format = AFMT_U8;
861 }
862
863 if (req_format == format) {
864 dmasound.soft.format = format;
865 dmasound.soft.size = size;
866 if (dmasound.minDev == SND_DEV_DSP) {
867 dmasound.dsp.format = format;
868 dmasound.dsp.size = size;
869 }
870 }
871
872 return format;
873}
874
875#define AWACS_VOLUME_TO_MASK(x) (15 - ((((x) - 1) * 15) / 99))
876#define AWACS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 15))
877
878static int awacs_get_volume(int reg, int lshift)
879{
880 int volume;
881
882 volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf);
883 volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8;
884 return volume;
885}
886
887static int awacs_volume_setter(int volume, int n, int mute, int lshift)
888{
889 int r1, rn;
890
891 if (mute && volume == 0) {
892 r1 = awacs_reg[1] | mute;
893 } else {
894 r1 = awacs_reg[1] & ~mute;
895 rn = awacs_reg[n] & ~(0xf | (0xf << lshift));
896 rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift);
897 rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf;
898 awacs_reg[n] = rn;
899 awacs_write((n << 12) | rn);
900 volume = awacs_get_volume(rn, lshift);
901 }
902 if (r1 != awacs_reg[1]) {
903 awacs_reg[1] = r1;
904 awacs_write(r1 | MASK_ADDR1);
905 }
906 return volume;
907}
908
909static int PMacSetVolume(int volume)
910{
911 printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
912 return 0;
913}
914
915static void awacs_setup_for_beep(int speed)
916{
917 out_le32(&awacs->control,
918 (in_le32(&awacs->control) & ~0x1f00)
919 | ((speed > 0 ? speed : awacs_rate_index) << 8));
920
921 if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
922 out_le32(&awacs->byteswap, BS_VAL);
923 else
924 out_le32(&awacs->byteswap, 0);
925}
926
927/* CHECK: how much of this *really* needs IRQs masked? */
928static void __PMacPlay(void)
929{
930 volatile struct dbdma_cmd *cp;
931 int next_frg, count;
932
933 count = 300 ; /* > two cycles at the lowest sample rate */
934
935 /* what we want to send next */
936 next_frg = (write_sq.front + write_sq.active) % write_sq.max_count;
937
938 if (awacs_beep_state) {
939 /* sound takes precedence over beeps */
940 /* stop the dma channel */
941 out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
942 while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
943 udelay(1);
944 if (awacs)
945 awacs_setup_for_beep(-1);
946 out_le32(&awacs_txdma->cmdptr,
947 virt_to_bus(&(awacs_tx_cmds[next_frg])));
948
949 beep_playing = 0;
950 awacs_beep_state = 0;
951 }
952 /* this won't allow more than two frags to be in the output queue at
953 once. (or one, if the max frags is 2 - because count can't exceed
954 2 in that case)
955 */
956 while (write_sq.active < 2 && write_sq.active < write_sq.count) {
957 count = (write_sq.count == write_sq.active + 1) ?
958 write_sq.rear_size:write_sq.block_size ;
959 if (count < write_sq.block_size) {
960 if (!write_sq.syncing) /* last block not yet filled,*/
961 break; /* and we're not syncing or POST-ed */
962 else {
963 /* pretend the block is full to force a new
964 block to be started on the next write */
965 write_sq.rear_size = write_sq.block_size ;
966 write_sq.syncing &= ~2 ; /* clear POST */
967 }
968 }
969 cp = &awacs_tx_cmds[next_frg];
970 st_le16(&cp->req_count, count);
971 st_le16(&cp->xfer_status, 0);
972 st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS);
973 /* put a STOP at the end of the queue - but only if we have
974 space for it. This means that, if we under-run and we only
975 have two fragments, we might re-play sound from an existing
976 queued frag. I guess the solution to that is not to set two
977 frags if you are likely to under-run...
978 */
979 if (write_sq.count < write_sq.max_count) {
980 if (++next_frg >= write_sq.max_count)
981 next_frg = 0 ; /* wrap */
982 /* if we get here then we've underrun so we will stop*/
983 st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP);
984 }
985 /* set the dbdma controller going, if it is not already */
986 if (write_sq.active == 0)
987 out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
988 (void)in_le32(&awacs_txdma->status);
989 out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
990 ++write_sq.active;
991 }
992}
993
994static void PMacPlay(void)
995{
996 LOCK();
997 if (!awacs_sleeping) {
998 unsigned long flags;
999
1000 spin_lock_irqsave(&dmasound.lock, flags);
1001 __PMacPlay();
1002 spin_unlock_irqrestore(&dmasound.lock, flags);
1003 }
1004 UNLOCK();
1005}
1006
1007static void PMacRecord(void)
1008{
1009 unsigned long flags;
1010
1011 if (read_sq.active)
1012 return;
1013
1014 spin_lock_irqsave(&dmasound.lock, flags);
1015
1016 /* This is all we have to do......Just start it up.
1017 */
1018 out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
1019 read_sq.active = 1;
1020
1021 spin_unlock_irqrestore(&dmasound.lock, flags);
1022}
1023
1024/* if the TX status comes up "DEAD" - reported on some Power Computing machines
1025 we need to re-start the dbdma - but from a different physical start address
1026 and with a different transfer length. It would get very messy to do this
1027 with the normal dbdma_cmd blocks - we would have to re-write the buffer start
1028 addresses each time. So, we will keep a single dbdma_cmd block which can be
1029 fiddled with.
1030 When DEAD status is first reported the content of the faulted dbdma block is
1031 copied into the emergency buffer and we note that the buffer is in use.
1032 we then bump the start physical address by the amount that was successfully
1033 output before it died.
1034 On any subsequent DEAD result we just do the bump-ups (we know that we are
1035 already using the emergency dbdma_cmd).
1036 CHECK: this just tries to "do it". It is possible that we should abandon
1037 xfers when the number of residual bytes gets below a certain value - I can
1038 see that this might cause a loop-forever if too small a transfer causes
1039 DEAD status. However this is a TODO for now - we'll see what gets reported.
1040 When we get a successful transfer result with the emergency buffer we just
1041 pretend that it completed using the original dmdma_cmd and carry on. The
1042 'next_cmd' field will already point back to the original loop of blocks.
1043*/
1044
1045static irqreturn_t
1046pmac_awacs_tx_intr(int irq, void *devid)
1047{
1048 int i = write_sq.front;
1049 int stat;
1050 int i_nowrap = write_sq.front;
1051 volatile struct dbdma_cmd *cp;
1052 /* != 0 when we are dealing with a DEAD xfer */
1053 static int emergency_in_use;
1054
1055 spin_lock(&dmasound.lock);
1056 while (write_sq.active > 0) { /* we expect to have done something*/
1057 if (emergency_in_use) /* we are dealing with DEAD xfer */
1058 cp = emergency_dbdma_cmd ;
1059 else
1060 cp = &awacs_tx_cmds[i];
1061 stat = ld_le16(&cp->xfer_status);
1062 if (stat & DEAD) {
1063 unsigned short req, res ;
1064 unsigned int phy ;
1065#ifdef DEBUG_DMASOUND
1066printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
1067#endif
1068 /* to clear DEAD status we must first clear RUN
1069 set it to quiescent to be on the safe side */
1070 (void)in_le32(&awacs_txdma->status);
1071 out_le32(&awacs_txdma->control,
1072 (RUN|PAUSE|FLUSH|WAKE) << 16);
1073 write_sq.died++ ;
1074 if (!emergency_in_use) { /* new problem */
1075 memcpy((void *)emergency_dbdma_cmd, (void *)cp,
1076 sizeof(struct dbdma_cmd));
1077 emergency_in_use = 1;
1078 cp = emergency_dbdma_cmd;
1079 }
1080 /* now bump the values to reflect the amount
1081 we haven't yet shifted */
1082 req = ld_le16(&cp->req_count);
1083 res = ld_le16(&cp->res_count);
1084 phy = ld_le32(&cp->phy_addr);
1085 phy += (req - res);
1086 st_le16(&cp->req_count, res);
1087 st_le16(&cp->res_count, 0);
1088 st_le16(&cp->xfer_status, 0);
1089 st_le32(&cp->phy_addr, phy);
1090 st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count]));
1091 st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
1092
1093 /* point at our patched up command block */
1094 out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
1095 /* we must re-start the controller */
1096 (void)in_le32(&awacs_txdma->status);
1097 /* should complete clearing the DEAD status */
1098 out_le32(&awacs_txdma->control,
1099 ((RUN|WAKE) << 16) + (RUN|WAKE));
1100 break; /* this block is still going */
1101 }
1102 if ((stat & ACTIVE) == 0)
1103 break; /* this frame is still going */
1104 if (emergency_in_use)
1105 emergency_in_use = 0 ; /* done that */
1106 --write_sq.count;
1107 --write_sq.active;
1108 i_nowrap++;
1109 if (++i >= write_sq.max_count)
1110 i = 0;
1111 }
1112
1113 /* if we stopped and we were not sync-ing - then we under-ran */
1114 if( write_sq.syncing == 0 ){
1115 stat = in_le32(&awacs_txdma->status) ;
1116 /* we hit the dbdma_stop */
1117 if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ;
1118 }
1119
1120 /* if we used some data up then wake the writer to supply some more*/
1121 if (i_nowrap != write_sq.front)
1122 WAKE_UP(write_sq.action_queue);
1123 write_sq.front = i;
1124
1125 /* but make sure we funnel what we've already got */\
1126 if (!awacs_sleeping)
1127 __PMacPlay();
1128
1129 /* make the wake-on-empty conditional on syncing */
1130 if (!write_sq.active && (write_sq.syncing & 1))
1131 WAKE_UP(write_sq.sync_queue); /* any time we're empty */
1132 spin_unlock(&dmasound.lock);
1133 return IRQ_HANDLED;
1134}
1135
1136
1137static irqreturn_t
1138pmac_awacs_rx_intr(int irq, void *devid)
1139{
1140 int stat ;
1141 /* For some reason on my PowerBook G3, I get one interrupt
1142 * when the interrupt vector is installed (like something is
1143 * pending). This happens before the dbdma is initialized by
1144 * us, so I just check the command pointer and if it is zero,
1145 * just blow it off.
1146 */
1147 if (in_le32(&awacs_rxdma->cmdptr) == 0)
1148 return IRQ_HANDLED;
1149
1150 /* We also want to blow 'em off when shutting down.
1151 */
1152 if (read_sq.active == 0)
1153 return IRQ_HANDLED;
1154
1155 spin_lock(&dmasound.lock);
1156 /* Check multiple buffers in case we were held off from
1157 * interrupt processing for a long time. Geeze, I really hope
1158 * this doesn't happen.
1159 */
1160 while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) {
1161
1162 /* if we got a "DEAD" status then just log it for now.
1163 and try to restart dma.
1164 TODO: figure out how best to fix it up
1165 */
1166 if (stat & DEAD){
1167#ifdef DEBUG_DMASOUND
1168printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
1169#endif
1170 /* to clear DEAD status we must first clear RUN
1171 set it to quiescent to be on the safe side */
1172 (void)in_le32(&awacs_txdma->status);
1173 out_le32(&awacs_txdma->control,
1174 (RUN|PAUSE|FLUSH|WAKE) << 16);
1175 awacs_rx_cmds[read_sq.rear].xfer_status = 0;
1176 awacs_rx_cmds[read_sq.rear].res_count = 0;
1177 read_sq.died++ ;
1178 (void)in_le32(&awacs_txdma->status);
1179 /* re-start the same block */
1180 out_le32(&awacs_rxdma->cmdptr,
1181 virt_to_bus(&awacs_rx_cmds[read_sq.rear]));
1182 /* we must re-start the controller */
1183 (void)in_le32(&awacs_rxdma->status);
1184 /* should complete clearing the DEAD status */
1185 out_le32(&awacs_rxdma->control,
1186 ((RUN|WAKE) << 16) + (RUN|WAKE));
1187 spin_unlock(&dmasound.lock);
1188 return IRQ_HANDLED; /* try this block again */
1189 }
1190 /* Clear status and move on to next buffer.
1191 */
1192 awacs_rx_cmds[read_sq.rear].xfer_status = 0;
1193 read_sq.rear++;
1194
1195 /* Wrap the buffer ring.
1196 */
1197 if (read_sq.rear >= read_sq.max_active)
1198 read_sq.rear = 0;
1199
1200 /* If we have caught up to the front buffer, bump it.
1201 * This will cause weird (but not fatal) results if the
1202 * read loop is currently using this buffer. The user is
1203 * behind in this case anyway, so weird things are going
1204 * to happen.
1205 */
1206 if (read_sq.rear == read_sq.front) {
1207 read_sq.front++;
1208 read_sq.xruns++ ; /* we overan */
1209 if (read_sq.front >= read_sq.max_active)
1210 read_sq.front = 0;
1211 }
1212 }
1213
1214 WAKE_UP(read_sq.action_queue);
1215 spin_unlock(&dmasound.lock);
1216 return IRQ_HANDLED;
1217}
1218
1219
1220static irqreturn_t
1221pmac_awacs_intr(int irq, void *devid)
1222{
1223 int ctrl;
1224 int status;
1225 int r1;
1226
1227 spin_lock(&dmasound.lock);
1228 ctrl = in_le32(&awacs->control);
1229 status = in_le32(&awacs->codec_stat);
1230
1231 if (ctrl & MASK_PORTCHG) {
1232 /* tested on Screamer, should work on others too */
1233 if (awacs_revision == AWACS_SCREAMER) {
1234 if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
1235 hdp_connected = 1;
1236
1237 r1 = awacs_reg[1] | MASK_SPKMUTE;
1238 awacs_reg[1] = r1;
1239 awacs_write(r1 | MASK_ADDR_MUTE);
1240 } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
1241 hdp_connected = 0;
1242
1243 r1 = awacs_reg[1] & ~MASK_SPKMUTE;
1244 awacs_reg[1] = r1;
1245 awacs_write(r1 | MASK_ADDR_MUTE);
1246 }
1247 }
1248 }
1249 if (ctrl & MASK_CNTLERR) {
1250 int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
1251 /* CHECK: we just swallow burgundy errors at the moment..*/
1252 if (err != 0 && awacs_revision != AWACS_BURGUNDY)
1253 printk(KERN_ERR "dmasound_pmac: error %x\n", err);
1254 }
1255 /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
1256 out_le32(&awacs->control, ctrl);
1257 spin_unlock(&dmasound.lock);
1258 return IRQ_HANDLED;
1259}
1260
1261static void
1262awacs_write(int val)
1263{
1264 int count = 300 ;
1265 if (awacs_revision >= AWACS_DACA || !awacs)
1266 return ;
1267
1268 while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
1269 udelay(1) ; /* timeout is > 2 samples at lowest rate */
1270 out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22));
1271 (void)in_le32(&awacs->byteswap);
1272}
1273
1274/* this is called when the beep timer expires... it will be called even
1275 if the beep has been overidden by other sound output.
1276*/
1277static void awacs_nosound(unsigned long xx)
1278{
1279 unsigned long flags;
1280 int count = 600 ; /* > four samples at lowest rate */
1281
1282 spin_lock_irqsave(&dmasound.lock, flags);
1283 if (beep_playing) {
1284 st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
1285 out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
1286 while ((in_le32(&awacs_txdma->status) & RUN) && count--)
1287 udelay(1);
1288 if (awacs)
1289 awacs_setup_for_beep(-1);
1290 beep_playing = 0;
1291 }
1292 spin_unlock_irqrestore(&dmasound.lock, flags);
1293}
1294
1295/*
1296 * We generate the beep with a single dbdma command that loops a buffer
1297 * forever - without generating interrupts.
1298 *
1299 * So, to stop it you have to stop dma output as per awacs_nosound.
1300 */
1301static int awacs_beep_event(struct input_dev *dev, unsigned int type,
1302 unsigned int code, int hz)
1303{
1304 unsigned long flags;
1305 int beep_speed = 0;
1306 int srate;
1307 int period, ncycles, nsamples;
1308 int i, j, f;
1309 short *p;
1310 static int beep_hz_cache;
1311 static int beep_nsamples_cache;
1312 static int beep_volume_cache;
1313
1314 if (type != EV_SND)
1315 return -1;
1316 switch (code) {
1317 case SND_BELL:
1318 if (hz)
1319 hz = 1000;
1320 break;
1321 case SND_TONE:
1322 break;
1323 default:
1324 return -1;
1325 }
1326
1327 if (beep_buf == NULL)
1328 return -1;
1329
1330 /* quick-hack fix for DACA, Burgundy & Tumbler */
1331
1332 if (awacs_revision >= AWACS_DACA){
1333 srate = 44100 ;
1334 } else {
1335 for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
1336 if (awacs_freqs_ok[i])
1337 beep_speed = i;
1338 srate = awacs_freqs[beep_speed];
1339 }
1340
1341 if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
1342 /* cancel beep currently playing */
1343 awacs_nosound(0);
1344 return 0;
1345 }
1346
1347 spin_lock_irqsave(&dmasound.lock, flags);
1348 if (beep_playing || write_sq.active || beep_buf == NULL) {
1349 spin_unlock_irqrestore(&dmasound.lock, flags);
1350 return -1; /* too hard, sorry :-( */
1351 }
1352 beep_playing = 1;
1353 st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
1354 spin_unlock_irqrestore(&dmasound.lock, flags);
1355
1356 if (hz == beep_hz_cache && beep_vol == beep_volume_cache) {
1357 nsamples = beep_nsamples_cache;
1358 } else {
1359 period = srate * 256 / hz; /* fixed point */
1360 ncycles = BEEP_BUFLEN * 256 / period;
1361 nsamples = (period * ncycles) >> 8;
1362 f = ncycles * 65536 / nsamples;
1363 j = 0;
1364 p = beep_buf;
1365 for (i = 0; i < nsamples; ++i, p += 2) {
1366 p[0] = p[1] = beep_wform[j >> 8] * beep_vol;
1367 j = (j + f) & 0xffff;
1368 }
1369 beep_hz_cache = hz;
1370 beep_volume_cache = beep_vol;
1371 beep_nsamples_cache = nsamples;
1372 }
1373
1374 st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
1375 st_le16(&beep_dbdma_cmd->xfer_status, 0);
1376 st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
1377 st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
1378 awacs_beep_state = 1;
1379
1380 spin_lock_irqsave(&dmasound.lock, flags);
1381 if (beep_playing) { /* i.e. haven't been terminated already */
1382 int count = 300 ;
1383 out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
1384 while ((in_le32(&awacs_txdma->status) & RUN) && count--)
1385 udelay(1); /* timeout > 2 samples at lowest rate*/
1386 if (awacs)
1387 awacs_setup_for_beep(beep_speed);
1388 out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
1389 (void)in_le32(&awacs_txdma->status);
1390 out_le32(&awacs_txdma->control, RUN | (RUN << 16));
1391 }
1392 spin_unlock_irqrestore(&dmasound.lock, flags);
1393
1394 return 0;
1395}
1396
1397/* used in init and for wake-up */
1398
1399static void
1400load_awacs(void)
1401{
1402 awacs_write(awacs_reg[0] + MASK_ADDR0);
1403 awacs_write(awacs_reg[1] + MASK_ADDR1);
1404 awacs_write(awacs_reg[2] + MASK_ADDR2);
1405 awacs_write(awacs_reg[4] + MASK_ADDR4);
1406
1407 if (awacs_revision == AWACS_SCREAMER) {
1408 awacs_write(awacs_reg[5] + MASK_ADDR5);
1409 msleep(100);
1410 awacs_write(awacs_reg[6] + MASK_ADDR6);
1411 msleep(2);
1412 awacs_write(awacs_reg[1] + MASK_ADDR1);
1413 awacs_write(awacs_reg[7] + MASK_ADDR7);
1414 }
1415 if (awacs) {
1416 if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
1417 out_le32(&awacs->byteswap, BS_VAL);
1418 else
1419 out_le32(&awacs->byteswap, 0);
1420 }
1421}
1422
1423#ifdef CONFIG_PM
1424/*
1425 * Save state when going to sleep, restore it afterwards.
1426 */
1427/* FIXME: sort out disabling/re-enabling of read stuff as well */
1428static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
1429{
1430 unsigned long flags;
1431
1432 switch (when) {
1433 case PBOOK_SLEEP_NOW:
1434 LOCK();
1435 awacs_sleeping = 1;
1436 /* Tell the rest of the driver we are now going to sleep */
1437 mb();
1438 if (awacs_revision == AWACS_SCREAMER ||
1439 awacs_revision == AWACS_AWACS) {
1440 awacs_reg1_save = awacs_reg[1];
1441 awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE;
1442 awacs_write(MASK_ADDR1 | awacs_reg[1]);
1443 }
1444
1445 PMacSilence();
1446 /* stop rx - if going - a bit of a daft user... but */
1447 out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
1448 /* deny interrupts */
1449 if (awacs)
1450 disable_irq(awacs_irq);
1451 disable_irq(awacs_tx_irq);
1452 disable_irq(awacs_rx_irq);
1453 /* Chip specific sleep code */
1454 switch (awacs_revision) {
1455 case AWACS_TUMBLER:
1456 case AWACS_SNAPPER:
1457 write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
1458 write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
1459 tas_enter_sleep();
1460 write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
1461 break ;
1462 case AWACS_DACA:
1463 daca_enter_sleep();
1464 break ;
1465 case AWACS_BURGUNDY:
1466 break ;
1467 case AWACS_SCREAMER:
1468 case AWACS_AWACS:
1469 default:
1470 out_le32(&awacs->control, 0x11) ;
1471 break ;
1472 }
1473 /* Disable sound clock */
1474 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
1475 /* According to Darwin, we do that after turning off the sound
1476 * chip clock. All this will have to be cleaned up once we properly
1477 * parse the OF sound-objects
1478 */
1479 if ((machine_is_compatible("PowerBook3,1") ||
1480 machine_is_compatible("PowerBook3,2")) && awacs) {
1481 awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
1482 awacs_write(MASK_ADDR1 | awacs_reg[1]);
1483 msleep(200);
1484 }
1485 break;
1486 case PBOOK_WAKE:
1487 /* Enable sound clock */
1488 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
1489 if ((machine_is_compatible("PowerBook3,1") ||
1490 machine_is_compatible("PowerBook3,2")) && awacs) {
1491 msleep(100);
1492 awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
1493 awacs_write(MASK_ADDR1 | awacs_reg[1]);
1494 msleep(300);
1495 } else
1496 msleep(1000);
1497 /* restore settings */
1498 switch (awacs_revision) {
1499 case AWACS_TUMBLER:
1500 case AWACS_SNAPPER:
1501 write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
1502 write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
1503 write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
1504 msleep(100);
1505 write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
1506 msleep(150);
1507 tas_leave_sleep(); /* Stub for now */
1508 headphone_intr(0, NULL);
1509 break;
1510 case AWACS_DACA:
1511 msleep(10); /* Check this !!! */
1512 daca_leave_sleep();
1513 break ; /* dont know how yet */
1514 case AWACS_BURGUNDY:
1515 break ;
1516 case AWACS_SCREAMER:
1517 case AWACS_AWACS:
1518 default:
1519 load_awacs() ;
1520 break ;
1521 }
1522 /* Recalibrate chip */
1523 if (awacs_revision == AWACS_SCREAMER && awacs)
1524 awacs_recalibrate();
1525 /* Make sure dma is stopped */
1526 PMacSilence();
1527 if (awacs)
1528 enable_irq(awacs_irq);
1529 enable_irq(awacs_tx_irq);
1530 enable_irq(awacs_rx_irq);
1531 if (awacs) {
1532 /* OK, allow ints back again */
1533 out_le32(&awacs->control, MASK_IEPC
1534 | (awacs_rate_index << 8) | 0x11
1535 | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
1536 }
1537 if (macio_base && is_pbook_g3) {
1538 /* FIXME: should restore the setup we had...*/
1539 out_8(macio_base + 0x37, 3);
1540 } else if (is_pbook_3X00) {
1541 in_8(latch_base + 0x190);
1542 }
1543 /* Remove mute */
1544 if (awacs_revision == AWACS_SCREAMER ||
1545 awacs_revision == AWACS_AWACS) {
1546 awacs_reg[1] = awacs_reg1_save;
1547 awacs_write(MASK_ADDR1 | awacs_reg[1]);
1548 }
1549 awacs_sleeping = 0;
1550 /* Resume pending sounds. */
1551 /* we don't try to restart input... */
1552 spin_lock_irqsave(&dmasound.lock, flags);
1553 __PMacPlay();
1554 spin_unlock_irqrestore(&dmasound.lock, flags);
1555 UNLOCK();
1556 }
1557}
1558#endif /* CONFIG_PM */
1559
1560
1561/* All the burgundy functions: */
1562
1563/* Waits for busy flag to clear */
1564static inline void
1565awacs_burgundy_busy_wait(void)
1566{
1567 int count = 50; /* > 2 samples at 44k1 */
1568 while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
1569 udelay(1) ;
1570}
1571
1572static inline void
1573awacs_burgundy_extend_wait(void)
1574{
1575 int count = 50 ; /* > 2 samples at 44k1 */
1576 while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--)
1577 udelay(1) ;
1578 count = 50;
1579 while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--)
1580 udelay(1);
1581}
1582
1583static void
1584awacs_burgundy_wcw(unsigned addr, unsigned val)
1585{
1586 out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
1587 awacs_burgundy_busy_wait();
1588 out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));
1589 awacs_burgundy_busy_wait();
1590 out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));
1591 awacs_burgundy_busy_wait();
1592 out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));
1593 awacs_burgundy_busy_wait();
1594}
1595
1596static unsigned
1597awacs_burgundy_rcw(unsigned addr)
1598{
1599 unsigned val = 0;
1600 unsigned long flags;
1601
1602 /* should have timeouts here */
1603 spin_lock_irqsave(&dmasound.lock, flags);
1604
1605 out_le32(&awacs->codec_ctrl, addr + 0x100000);
1606 awacs_burgundy_busy_wait();
1607 awacs_burgundy_extend_wait();
1608 val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
1609
1610 out_le32(&awacs->codec_ctrl, addr + 0x100100);
1611 awacs_burgundy_busy_wait();
1612 awacs_burgundy_extend_wait();
1613 val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8;
1614
1615 out_le32(&awacs->codec_ctrl, addr + 0x100200);
1616 awacs_burgundy_busy_wait();
1617 awacs_burgundy_extend_wait();
1618 val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16;
1619
1620 out_le32(&awacs->codec_ctrl, addr + 0x100300);
1621 awacs_burgundy_busy_wait();
1622 awacs_burgundy_extend_wait();
1623 val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;
1624
1625 spin_unlock_irqrestore(&dmasound.lock, flags);
1626
1627 return val;
1628}
1629
1630
1631static void
1632awacs_burgundy_wcb(unsigned addr, unsigned val)
1633{
1634 out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
1635 awacs_burgundy_busy_wait();
1636}
1637
1638static unsigned
1639awacs_burgundy_rcb(unsigned addr)
1640{
1641 unsigned val = 0;
1642 unsigned long flags;
1643
1644 /* should have timeouts here */
1645 spin_lock_irqsave(&dmasound.lock, flags);
1646
1647 out_le32(&awacs->codec_ctrl, addr + 0x100000);
1648 awacs_burgundy_busy_wait();
1649 awacs_burgundy_extend_wait();
1650 val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
1651
1652 spin_unlock_irqrestore(&dmasound.lock, flags);
1653
1654 return val;
1655}
1656
1657static int
1658awacs_burgundy_check(void)
1659{
1660 /* Checks to see the chip is alive and kicking */
1661 int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE;
1662
1663 return error == 0xf0000;
1664}
1665
1666static int
1667awacs_burgundy_init(void)
1668{
1669 if (awacs_burgundy_check()) {
1670 printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n");
1671 return 1;
1672 }
1673
1674 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES,
1675 DEF_BURGUNDY_OUTPUTENABLES);
1676 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
1677 DEF_BURGUNDY_MORE_OUTPUTENABLES);
1678 awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS,
1679 DEF_BURGUNDY_OUTPUTSELECTS);
1680
1681 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21,
1682 DEF_BURGUNDY_INPSEL21);
1683 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3,
1684 DEF_BURGUNDY_INPSEL3);
1685 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD,
1686 DEF_BURGUNDY_GAINCD);
1687 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE,
1688 DEF_BURGUNDY_GAINLINE);
1689 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC,
1690 DEF_BURGUNDY_GAINMIC);
1691 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM,
1692 DEF_BURGUNDY_GAINMODEM);
1693
1694 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER,
1695 DEF_BURGUNDY_ATTENSPEAKER);
1696 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT,
1697 DEF_BURGUNDY_ATTENLINEOUT);
1698 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP,
1699 DEF_BURGUNDY_ATTENHP);
1700
1701 awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME,
1702 DEF_BURGUNDY_MASTER_VOLUME);
1703 awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD,
1704 DEF_BURGUNDY_VOLCD);
1705 awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE,
1706 DEF_BURGUNDY_VOLLINE);
1707 awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC,
1708 DEF_BURGUNDY_VOLMIC);
1709 return 0;
1710}
1711
1712static void
1713awacs_burgundy_write_volume(unsigned address, int volume)
1714{
1715 int hardvolume,lvolume,rvolume;
1716
1717 lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0;
1718 rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0;
1719
1720 hardvolume = lvolume + (rvolume << 16);
1721
1722 awacs_burgundy_wcw(address, hardvolume);
1723}
1724
1725static int
1726awacs_burgundy_read_volume(unsigned address)
1727{
1728 int softvolume,wvolume;
1729
1730 wvolume = awacs_burgundy_rcw(address);
1731
1732 softvolume = (wvolume & 0xff) - 155;
1733 softvolume += (((wvolume >> 16) & 0xff) - 155)<<8;
1734
1735 return softvolume > 0 ? softvolume : 0;
1736}
1737
1738static int
1739awacs_burgundy_read_mvolume(unsigned address)
1740{
1741 int lvolume,rvolume,wvolume;
1742
1743 wvolume = awacs_burgundy_rcw(address);
1744
1745 wvolume &= 0xffff;
1746
1747 rvolume = (wvolume & 0xff) - 155;
1748 lvolume = ((wvolume & 0xff00)>>8) - 155;
1749
1750 return lvolume + (rvolume << 8);
1751}
1752
1753static void
1754awacs_burgundy_write_mvolume(unsigned address, int volume)
1755{
1756 int lvolume,rvolume,hardvolume;
1757
1758 lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0;
1759 rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0;
1760
1761 hardvolume = lvolume + (rvolume << 8);
1762 hardvolume += (hardvolume << 16);
1763
1764 awacs_burgundy_wcw(address, hardvolume);
1765}
1766
1767/* End burgundy functions */
1768
1769/* Set up output volumes on machines with the 'perch/whisper' extension card.
1770 * this has an SGS i2c chip (7433) which is accessed using the cuda.
1771 *
1772 * TODO: split this out and make use of the other parts of the SGS chip to
1773 * do Bass, Treble etc.
1774 */
1775
1776static void
1777awacs_enable_amp(int spkr_vol)
1778{
1779#ifdef CONFIG_ADB_CUDA
1780 struct adb_request req;
1781
1782 if (sys_ctrler != SYS_CTRLER_CUDA)
1783 return;
1784
1785 /* turn on headphones */
1786 cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
1787 0x8a, 4, 0);
1788 while (!req.complete) cuda_poll();
1789 cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
1790 0x8a, 6, 0);
1791 while (!req.complete) cuda_poll();
1792
1793 /* turn on speaker */
1794 cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
1795 0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100);
1796 while (!req.complete) cuda_poll();
1797 cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
1798 0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100);
1799 while (!req.complete) cuda_poll();
1800
1801 cuda_request(&req, NULL, 5, CUDA_PACKET,
1802 CUDA_GET_SET_IIC, 0x8a, 1, 0x29);
1803 while (!req.complete) cuda_poll();
1804#endif /* CONFIG_ADB_CUDA */
1805}
1806
1807
1808/*** Mid level stuff *********************************************************/
1809
1810
1811/*
1812 * /dev/mixer abstraction
1813 */
1814
1815static void do_line_lev(int data)
1816{
1817 line_lev = data ;
1818 awacs_reg[0] &= ~MASK_MUX_AUDIN;
1819 if ((data & 0xff) >= 50)
1820 awacs_reg[0] |= MASK_MUX_AUDIN;
1821 awacs_write(MASK_ADDR0 | awacs_reg[0]);
1822}
1823
1824static void do_ip_gain(int data)
1825{
1826 ip_gain = data ;
1827 data &= 0xff;
1828 awacs_reg[0] &= ~MASK_GAINLINE;
1829 if (awacs_revision == AWACS_SCREAMER) {
1830 awacs_reg[6] &= ~MASK_MIC_BOOST ;
1831 if (data >= 33) {
1832 awacs_reg[0] |= MASK_GAINLINE;
1833 if( data >= 66)
1834 awacs_reg[6] |= MASK_MIC_BOOST ;
1835 }
1836 awacs_write(MASK_ADDR6 | awacs_reg[6]) ;
1837 } else {
1838 if (data >= 50)
1839 awacs_reg[0] |= MASK_GAINLINE;
1840 }
1841 awacs_write(MASK_ADDR0 | awacs_reg[0]);
1842}
1843
1844static void do_mic_lev(int data)
1845{
1846 mic_lev = data ;
1847 data &= 0xff;
1848 awacs_reg[0] &= ~MASK_MUX_MIC;
1849 if (data >= 50)
1850 awacs_reg[0] |= MASK_MUX_MIC;
1851 awacs_write(MASK_ADDR0 | awacs_reg[0]);
1852}
1853
1854static void do_cd_lev(int data)
1855{
1856 cd_lev = data ;
1857 awacs_reg[0] &= ~MASK_MUX_CD;
1858 if ((data & 0xff) >= 50)
1859 awacs_reg[0] |= MASK_MUX_CD;
1860 awacs_write(MASK_ADDR0 | awacs_reg[0]);
1861}
1862
1863static void do_rec_lev(int data)
1864{
1865 int left, right ;
1866 rec_lev = data ;
1867 /* need to fudge this to use the volume setter routine */
1868 left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ;
1869 right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ;
1870 left |= (right << 8 );
1871 left = awacs_volume_setter(left, 0, 0, 4);
1872}
1873
1874static void do_passthru_vol(int data)
1875{
1876 passthru_vol = data ;
1877 awacs_reg[1] &= ~MASK_LOOPTHRU;
1878 if (awacs_revision == AWACS_SCREAMER) {
1879 if( data ) { /* switch it on for non-zero */
1880 awacs_reg[1] |= MASK_LOOPTHRU;
1881 awacs_write(MASK_ADDR1 | awacs_reg[1]);
1882 }
1883 data = awacs_volume_setter(data, 5, 0, 6) ;
1884 } else {
1885 if ((data & 0xff) >= 50)
1886 awacs_reg[1] |= MASK_LOOPTHRU;
1887 awacs_write(MASK_ADDR1 | awacs_reg[1]);
1888 data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;
1889 }
1890}
1891
1892static int awacs_mixer_ioctl(u_int cmd, u_long arg)
1893{
1894 int data;
1895 int rc;
1896
1897 switch (cmd) {
1898 case SOUND_MIXER_READ_CAPS:
1899 /* say we will allow multiple inputs? prob. wrong
1900 so I'm switching it to single */
1901 return IOCTL_OUT(arg, 1);
1902 case SOUND_MIXER_READ_DEVMASK:
1903 data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
1904 | SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD
1905 | SOUND_MASK_IGAIN | SOUND_MASK_RECLEV
1906 | SOUND_MASK_ALTPCM
1907 | SOUND_MASK_MONITOR;
1908 rc = IOCTL_OUT(arg, data);
1909 break;
1910 case SOUND_MIXER_READ_RECMASK:
1911 data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD;
1912 rc = IOCTL_OUT(arg, data);
1913 break;
1914 case SOUND_MIXER_READ_RECSRC:
1915 data = 0;
1916 if (awacs_reg[0] & MASK_MUX_AUDIN)
1917 data |= SOUND_MASK_LINE;
1918 if (awacs_reg[0] & MASK_MUX_MIC)
1919 data |= SOUND_MASK_MIC;
1920 if (awacs_reg[0] & MASK_MUX_CD)
1921 data |= SOUND_MASK_CD;
1922 rc = IOCTL_OUT(arg, data);
1923 break;
1924 case SOUND_MIXER_WRITE_RECSRC:
1925 IOCTL_IN(arg, data);
1926 data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD);
1927 awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
1928 | MASK_MUX_AUDIN);
1929 if (data & SOUND_MASK_LINE)
1930 awacs_reg[0] |= MASK_MUX_AUDIN;
1931 if (data & SOUND_MASK_MIC)
1932 awacs_reg[0] |= MASK_MUX_MIC;
1933 if (data & SOUND_MASK_CD)
1934 awacs_reg[0] |= MASK_MUX_CD;
1935 awacs_write(awacs_reg[0] | MASK_ADDR0);
1936 rc = IOCTL_OUT(arg, data);
1937 break;
1938 case SOUND_MIXER_READ_STEREODEVS:
1939 data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV ;
1940 if (awacs_revision == AWACS_SCREAMER)
1941 data |= SOUND_MASK_MONITOR ;
1942 rc = IOCTL_OUT(arg, data);
1943 break;
1944 case SOUND_MIXER_WRITE_VOLUME:
1945 IOCTL_IN(arg, data);
1946 line_vol = data ;
1947 awacs_volume_setter(data, 2, 0, 6);
1948 /* fall through */
1949 case SOUND_MIXER_READ_VOLUME:
1950 rc = IOCTL_OUT(arg, line_vol);
1951 break;
1952 case SOUND_MIXER_WRITE_SPEAKER:
1953 IOCTL_IN(arg, data);
1954 spk_vol = data ;
1955 if (has_perch)
1956 awacs_enable_amp(data);
1957 else
1958 (void)awacs_volume_setter(data, 4, MASK_CMUTE, 6);
1959 /* fall though */
1960 case SOUND_MIXER_READ_SPEAKER:
1961 rc = IOCTL_OUT(arg, spk_vol);
1962 break;
1963 case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
1964 IOCTL_IN(arg, data);
1965 beep_vol = data & 0xff;
1966 /* fall through */
1967 case SOUND_MIXER_READ_ALTPCM:
1968 rc = IOCTL_OUT(arg, beep_vol);
1969 break;
1970 case SOUND_MIXER_WRITE_LINE:
1971 IOCTL_IN(arg, data);
1972 do_line_lev(data) ;
1973 /* fall through */
1974 case SOUND_MIXER_READ_LINE:
1975 rc = IOCTL_OUT(arg, line_lev);
1976 break;
1977 case SOUND_MIXER_WRITE_IGAIN:
1978 IOCTL_IN(arg, data);
1979 do_ip_gain(data) ;
1980 /* fall through */
1981 case SOUND_MIXER_READ_IGAIN:
1982 rc = IOCTL_OUT(arg, ip_gain);
1983 break;
1984 case SOUND_MIXER_WRITE_MIC:
1985 IOCTL_IN(arg, data);
1986 do_mic_lev(data);
1987 /* fall through */
1988 case SOUND_MIXER_READ_MIC:
1989 rc = IOCTL_OUT(arg, mic_lev);
1990 break;
1991 case SOUND_MIXER_WRITE_CD:
1992 IOCTL_IN(arg, data);
1993 do_cd_lev(data);
1994 /* fall through */
1995 case SOUND_MIXER_READ_CD:
1996 rc = IOCTL_OUT(arg, cd_lev);
1997 break;
1998 case SOUND_MIXER_WRITE_RECLEV:
1999 IOCTL_IN(arg, data);
2000 do_rec_lev(data) ;
2001 /* fall through */
2002 case SOUND_MIXER_READ_RECLEV:
2003 rc = IOCTL_OUT(arg, rec_lev);
2004 break;
2005 case MIXER_WRITE(SOUND_MIXER_MONITOR):
2006 IOCTL_IN(arg, data);
2007 do_passthru_vol(data) ;
2008 /* fall through */
2009 case MIXER_READ(SOUND_MIXER_MONITOR):
2010 rc = IOCTL_OUT(arg, passthru_vol);
2011 break;
2012 default:
2013 rc = -EINVAL;
2014 }
2015
2016 return rc;
2017}
2018
2019static void awacs_mixer_init(void)
2020{
2021 awacs_volume_setter(line_vol, 2, 0, 6);
2022 if (has_perch)
2023 awacs_enable_amp(spk_vol);
2024 else
2025 (void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6);
2026 do_line_lev(line_lev) ;
2027 do_ip_gain(ip_gain) ;
2028 do_mic_lev(mic_lev) ;
2029 do_cd_lev(cd_lev) ;
2030 do_rec_lev(rec_lev) ;
2031 do_passthru_vol(passthru_vol) ;
2032}
2033
2034static int burgundy_mixer_ioctl(u_int cmd, u_long arg)
2035{
2036 int data;
2037 int rc;
2038
2039 /* We are, we are, we are... Burgundy or better */
2040 switch(cmd) {
2041 case SOUND_MIXER_READ_DEVMASK:
2042 data = SOUND_MASK_VOLUME | SOUND_MASK_CD |
2043 SOUND_MASK_LINE | SOUND_MASK_MIC |
2044 SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;
2045 rc = IOCTL_OUT(arg, data);
2046 break;
2047 case SOUND_MIXER_READ_RECMASK:
2048 data = SOUND_MASK_LINE | SOUND_MASK_MIC
2049 | SOUND_MASK_CD;
2050 rc = IOCTL_OUT(arg, data);
2051 break;
2052 case SOUND_MIXER_READ_RECSRC:
2053 data = 0;
2054 if (awacs_reg[0] & MASK_MUX_AUDIN)
2055 data |= SOUND_MASK_LINE;
2056 if (awacs_reg[0] & MASK_MUX_MIC)
2057 data |= SOUND_MASK_MIC;
2058 if (awacs_reg[0] & MASK_MUX_CD)
2059 data |= SOUND_MASK_CD;
2060 rc = IOCTL_OUT(arg, data);
2061 break;
2062 case SOUND_MIXER_WRITE_RECSRC:
2063 IOCTL_IN(arg, data);
2064 data &= (SOUND_MASK_LINE
2065 | SOUND_MASK_MIC | SOUND_MASK_CD);
2066 awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
2067 | MASK_MUX_AUDIN);
2068 if (data & SOUND_MASK_LINE)
2069 awacs_reg[0] |= MASK_MUX_AUDIN;
2070 if (data & SOUND_MASK_MIC)
2071 awacs_reg[0] |= MASK_MUX_MIC;
2072 if (data & SOUND_MASK_CD)
2073 awacs_reg[0] |= MASK_MUX_CD;
2074 awacs_write(awacs_reg[0] | MASK_ADDR0);
2075 rc = IOCTL_OUT(arg, data);
2076 break;
2077 case SOUND_MIXER_READ_STEREODEVS:
2078 data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
2079 | SOUND_MASK_RECLEV | SOUND_MASK_CD
2080 | SOUND_MASK_LINE;
2081 rc = IOCTL_OUT(arg, data);
2082 break;
2083 case SOUND_MIXER_READ_CAPS:
2084 rc = IOCTL_OUT(arg, 0);
2085 break;
2086 case SOUND_MIXER_WRITE_VOLUME:
2087 IOCTL_IN(arg, data);
2088 awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data);
2089 /* Fall through */
2090 case SOUND_MIXER_READ_VOLUME:
2091 rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME));
2092 break;
2093 case SOUND_MIXER_WRITE_SPEAKER:
2094 IOCTL_IN(arg, data);
2095 if (!(data & 0xff)) {
2096 /* Mute the left speaker */
2097 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
2098 awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2);
2099 } else {
2100 /* Unmute the left speaker */
2101 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
2102 awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2);
2103 }
2104 if (!(data & 0xff00)) {
2105 /* Mute the right speaker */
2106 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
2107 awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4);
2108 } else {
2109 /* Unmute the right speaker */
2110 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
2111 awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4);
2112 }
2113
2114 data = (((data&0xff)*16)/100 > 0xf ? 0xf :
2115 (((data&0xff)*16)/100)) +
2116 ((((data>>8)*16)/100 > 0xf ? 0xf :
2117 ((((data>>8)*16)/100)))<<4);
2118
2119 awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data);
2120 /* Fall through */
2121 case SOUND_MIXER_READ_SPEAKER:
2122 data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
2123 data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
2124 rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
2125 break;
2126 case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
2127 IOCTL_IN(arg, data);
2128 beep_vol = data & 0xff;
2129 /* fall through */
2130 case SOUND_MIXER_READ_ALTPCM:
2131 rc = IOCTL_OUT(arg, beep_vol);
2132 break;
2133 case SOUND_MIXER_WRITE_LINE:
2134 IOCTL_IN(arg, data);
2135 awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data);
2136
2137 /* fall through */
2138 case SOUND_MIXER_READ_LINE:
2139 data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE);
2140 rc = IOCTL_OUT(arg, data);
2141 break;
2142 case SOUND_MIXER_WRITE_MIC:
2143 IOCTL_IN(arg, data);
2144 /* Mic is mono device */
2145 data = (data << 8) + (data << 24);
2146 awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data);
2147 /* fall through */
2148 case SOUND_MIXER_READ_MIC:
2149 data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC);
2150 data <<= 24;
2151 rc = IOCTL_OUT(arg, data);
2152 break;
2153 case SOUND_MIXER_WRITE_CD:
2154 IOCTL_IN(arg, data);
2155 awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data);
2156 /* fall through */
2157 case SOUND_MIXER_READ_CD:
2158 data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD);
2159 rc = IOCTL_OUT(arg, data);
2160 break;
2161 case SOUND_MIXER_WRITE_RECLEV:
2162 IOCTL_IN(arg, data);
2163 data = awacs_volume_setter(data, 0, 0, 4);
2164 rc = IOCTL_OUT(arg, data);
2165 break;
2166 case SOUND_MIXER_READ_RECLEV:
2167 data = awacs_get_volume(awacs_reg[0], 4);
2168 rc = IOCTL_OUT(arg, data);
2169 break;
2170 case SOUND_MIXER_OUTMASK:
2171 case SOUND_MIXER_OUTSRC:
2172 default:
2173 rc = -EINVAL;
2174 }
2175
2176 return rc;
2177}
2178
2179static int daca_mixer_ioctl(u_int cmd, u_long arg)
2180{
2181 int data;
2182 int rc;
2183
2184 /* And the DACA's no genius either! */
2185
2186 switch(cmd) {
2187 case SOUND_MIXER_READ_DEVMASK:
2188 data = SOUND_MASK_VOLUME;
2189 rc = IOCTL_OUT(arg, data);
2190 break;
2191 case SOUND_MIXER_READ_RECMASK:
2192 data = 0;
2193 rc = IOCTL_OUT(arg, data);
2194 break;
2195 case SOUND_MIXER_READ_RECSRC:
2196 data = 0;
2197 rc = IOCTL_OUT(arg, data);
2198 break;
2199 case SOUND_MIXER_WRITE_RECSRC:
2200 IOCTL_IN(arg, data);
2201 data =0;
2202 rc = IOCTL_OUT(arg, data);
2203 break;
2204 case SOUND_MIXER_READ_STEREODEVS:
2205 data = SOUND_MASK_VOLUME;
2206 rc = IOCTL_OUT(arg, data);
2207 break;
2208 case SOUND_MIXER_READ_CAPS:
2209 rc = IOCTL_OUT(arg, 0);
2210 break;
2211 case SOUND_MIXER_WRITE_VOLUME:
2212 IOCTL_IN(arg, data);
2213 daca_set_volume(data, data);
2214 /* Fall through */
2215 case SOUND_MIXER_READ_VOLUME:
2216 daca_get_volume(& data, &data);
2217 rc = IOCTL_OUT(arg, data);
2218 break;
2219 case SOUND_MIXER_OUTMASK:
2220 case SOUND_MIXER_OUTSRC:
2221 default:
2222 rc = -EINVAL;
2223 }
2224 return rc;
2225}
2226
2227static int PMacMixerIoctl(u_int cmd, u_long arg)
2228{
2229 int rc;
2230
2231 /* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */
2232
2233 TRY_LOCK();
2234
2235 switch (awacs_revision){
2236 case AWACS_BURGUNDY:
2237 rc = burgundy_mixer_ioctl(cmd, arg);
2238 break ;
2239 case AWACS_DACA:
2240 rc = daca_mixer_ioctl(cmd, arg);
2241 break;
2242 case AWACS_TUMBLER:
2243 case AWACS_SNAPPER:
2244 rc = tas_mixer_ioctl(cmd, arg);
2245 break ;
2246 default: /* ;-)) */
2247 rc = awacs_mixer_ioctl(cmd, arg);
2248 }
2249
2250 UNLOCK();
2251
2252 return rc;
2253}
2254
2255static void PMacMixerInit(void)
2256{
2257 switch (awacs_revision) {
2258 case AWACS_TUMBLER:
2259 printk("AE-Init tumbler mixer\n");
2260 break ;
2261 case AWACS_SNAPPER:
2262 printk("AE-Init snapper mixer\n");
2263 break ;
2264 case AWACS_DACA:
2265 case AWACS_BURGUNDY:
2266 break ; /* don't know yet */
2267 case AWACS_AWACS:
2268 case AWACS_SCREAMER:
2269 default:
2270 awacs_mixer_init() ;
2271 break ;
2272 }
2273}
2274
2275/* Write/Read sq setup functions:
2276 Check to see if we have enough (or any) dbdma cmd buffers for the
2277 user's fragment settings. If not, allocate some. If this fails we will
2278 point at the beep buffer - as an emergency provision - to stop dma tromping
2279 on some random bit of memory (if someone lets it go anyway).
2280 The command buffers are then set up to point to the fragment buffers
2281 (allocated elsewhere). We need n+1 commands the last of which holds
2282 a NOP + loop to start.
2283*/
2284
2285static int PMacWriteSqSetup(void)
2286{
2287 int i, count = 600 ;
2288 volatile struct dbdma_cmd *cp;
2289
2290 LOCK();
2291
2292 /* stop the controller from doing any output - if it isn't already.
2293 it _should_ be before this is called anyway */
2294
2295 out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
2296 while ((in_le32(&awacs_txdma->status) & RUN) && count--)
2297 udelay(1);
2298#ifdef DEBUG_DMASOUND
2299if (count <= 0)
2300 printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n");
2301#endif
2302
2303 if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
2304 kfree(awacs_tx_cmd_space);
2305 number_of_tx_cmd_buffers = 0;
2306
2307 /* we need nbufs + 1 (for the loop) and we should request + 1
2308 again because the DBDMA_ALIGN might pull the start up by up
2309 to sizeof(struct dbdma_cmd) - 4.
2310 */
2311
2312 awacs_tx_cmd_space = kmalloc
2313 ((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
2314 GFP_KERNEL);
2315 if (awacs_tx_cmd_space == NULL) {
2316 /* don't leave it dangling - nasty but better than a
2317 random address */
2318 out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
2319 printk(KERN_ERR
2320 "dmasound_pmac: can't allocate dbdma cmd buffers"
2321 ", driver disabled\n");
2322 UNLOCK();
2323 return -ENOMEM;
2324 }
2325 awacs_tx_cmds = (volatile struct dbdma_cmd *)
2326 DBDMA_ALIGN(awacs_tx_cmd_space);
2327 number_of_tx_cmd_buffers = write_sq.max_count + 1;
2328 }
2329
2330 cp = awacs_tx_cmds;
2331 memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd));
2332 for (i = 0; i < write_sq.max_count; ++i, ++cp) {
2333 st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i]));
2334 }
2335 st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
2336 st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds));
2337 /* point the controller at the command stack - ready to go */
2338 out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds));
2339 UNLOCK();
2340 return 0;
2341}
2342
2343static int PMacReadSqSetup(void)
2344{
2345 int i, count = 600;
2346 volatile struct dbdma_cmd *cp;
2347
2348 LOCK();
2349
2350 /* stop the controller from doing any input - if it isn't already.
2351 it _should_ be before this is called anyway */
2352
2353 out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
2354 while ((in_le32(&awacs_rxdma->status) & RUN) && count--)
2355 udelay(1);
2356#ifdef DEBUG_DMASOUND
2357if (count <= 0)
2358 printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n");
2359#endif
2360
2361 if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
2362 kfree(awacs_rx_cmd_space);
2363 number_of_rx_cmd_buffers = 0;
2364
2365 /* we need nbufs + 1 (for the loop) and we should request + 1 again
2366 because the DBDMA_ALIGN might pull the start up by up to
2367 sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits).
2368 */
2369
2370 awacs_rx_cmd_space = kmalloc
2371 ((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
2372 GFP_KERNEL);
2373 if (awacs_rx_cmd_space == NULL) {
2374 /* don't leave it dangling - nasty but better than a
2375 random address */
2376 out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
2377 printk(KERN_ERR
2378 "dmasound_pmac: can't allocate dbdma cmd buffers"
2379 ", driver disabled\n");
2380 UNLOCK();
2381 return -ENOMEM;
2382 }
2383 awacs_rx_cmds = (volatile struct dbdma_cmd *)
2384 DBDMA_ALIGN(awacs_rx_cmd_space);
2385 number_of_rx_cmd_buffers = read_sq.max_count + 1 ;
2386 }
2387 cp = awacs_rx_cmds;
2388 memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd));
2389
2390 /* Set dma buffers up in a loop */
2391 for (i = 0; i < read_sq.max_count; i++,cp++) {
2392 st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i]));
2393 st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS);
2394 st_le16(&cp->req_count, read_sq.block_size);
2395 st_le16(&cp->xfer_status, 0);
2396 }
2397
2398 /* The next two lines make the thing loop around.
2399 */
2400 st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
2401 st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds));
2402 /* point the controller at the command stack - ready to go */
2403 out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds));
2404
2405 UNLOCK();
2406 return 0;
2407}
2408
2409/* TODO: this needs work to guarantee that when it returns DMA has stopped
2410 but in a more elegant way than is done here....
2411*/
2412
2413static void PMacAbortRead(void)
2414{
2415 int i;
2416 volatile struct dbdma_cmd *cp;
2417
2418 LOCK();
2419 /* give it a chance to update the output and provide the IRQ
2420 that is expected.
2421 */
2422
2423 out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH );
2424
2425 cp = awacs_rx_cmds;
2426 for (i = 0; i < read_sq.max_count; i++,cp++)
2427 st_le16(&cp->command, DBDMA_STOP);
2428 /*
2429 * We should probably wait for the thing to stop before we
2430 * release the memory.
2431 */
2432
2433 msleep(100) ; /* give it a (small) chance to act */
2434
2435 /* apply the sledgehammer approach - just stop it now */
2436
2437 out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
2438 UNLOCK();
2439}
2440
2441extern char *get_afmt_string(int);
2442static int PMacStateInfo(char *b, size_t sp)
2443{
2444 int i, len = 0;
2445 len = sprintf(b,"HW rates: ");
2446 switch (awacs_revision){
2447 case AWACS_DACA:
2448 case AWACS_BURGUNDY:
2449 len += sprintf(b,"44100 ") ;
2450 break ;
2451 case AWACS_TUMBLER:
2452 case AWACS_SNAPPER:
2453 for (i=0; i<1; i++){
2454 if (tas_freqs_ok[i])
2455 len += sprintf(b+len,"%d ", tas_freqs[i]) ;
2456 }
2457 break ;
2458 case AWACS_AWACS:
2459 case AWACS_SCREAMER:
2460 default:
2461 for (i=0; i<8; i++){
2462 if (awacs_freqs_ok[i])
2463 len += sprintf(b+len,"%d ", awacs_freqs[i]) ;
2464 }
2465 break ;
2466 }
2467 len += sprintf(b+len,"s/sec\n") ;
2468 if (len < sp) {
2469 len += sprintf(b+len,"HW AFMTS: ");
2470 i = AFMT_U16_BE ;
2471 while (i) {
2472 if (i & dmasound.mach.hardware_afmts)
2473 len += sprintf(b+len,"%s ",
2474 get_afmt_string(i & dmasound.mach.hardware_afmts));
2475 i >>= 1 ;
2476 }
2477 len += sprintf(b+len,"\n") ;
2478 }
2479 return len ;
2480}
2481
2482/*** Machine definitions *****************************************************/
2483
2484static SETTINGS def_hard = {
2485 .format = AFMT_S16_BE,
2486 .stereo = 1,
2487 .size = 16,
2488 .speed = 44100
2489} ;
2490
2491static SETTINGS def_soft = {
2492 .format = AFMT_S16_BE,
2493 .stereo = 1,
2494 .size = 16,
2495 .speed = 44100
2496} ;
2497
2498static MACHINE machPMac = {
2499 .name = awacs_name,
2500 .name2 = "PowerMac Built-in Sound",
2501 .owner = THIS_MODULE,
2502 .dma_alloc = PMacAlloc,
2503 .dma_free = PMacFree,
2504 .irqinit = PMacIrqInit,
2505#ifdef MODULE
2506 .irqcleanup = PMacIrqCleanup,
2507#endif /* MODULE */
2508 .init = PMacInit,
2509 .silence = PMacSilence,
2510 .setFormat = PMacSetFormat,
2511 .setVolume = PMacSetVolume,
2512 .play = PMacPlay,
2513 .record = NULL, /* default to no record */
2514 .mixer_init = PMacMixerInit,
2515 .mixer_ioctl = PMacMixerIoctl,
2516 .write_sq_setup = PMacWriteSqSetup,
2517 .read_sq_setup = PMacReadSqSetup,
2518 .state_info = PMacStateInfo,
2519 .abort_read = PMacAbortRead,
2520 .min_dsp_speed = 7350,
2521 .max_dsp_speed = 44100,
2522 .version = ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION)
2523};
2524
2525
2526/*** Config & Setup **********************************************************/
2527
2528/* Check for pmac models that we care about in terms of special actions.
2529*/
2530
2531void __init
2532set_model(void)
2533{
2534 /* portables/lap-tops */
2535
2536 if (machine_is_compatible("AAPL,3400/2400") ||
2537 machine_is_compatible("AAPL,3500")) {
2538 is_pbook_3X00 = 1 ;
2539 }
2540 if (machine_is_compatible("PowerBook1,1") || /* lombard */
2541 machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */
2542 is_pbook_g3 = 1 ;
2543 return ;
2544 }
2545}
2546
2547/* Get the OF node that tells us about the registers, interrupts etc. to use
2548 for sound IO.
2549
2550 On most machines the sound IO OF node is the 'davbus' node. On newer pmacs
2551 with DACA (& Tumbler) the node to use is i2s-a. On much older machines i.e.
2552 before 9500 there is no davbus node and we have to use the 'awacs' property.
2553
2554 In the latter case we signal this by setting the codec value - so that the
2555 code that looks for chip properties knows how to go about it.
2556*/
2557
2558static struct device_node* __init
2559get_snd_io_node(void)
2560{
2561 struct device_node *np;
2562
2563 /* set up awacs_node for early OF which doesn't have a full set of
2564 * properties on davbus
2565 */
2566 awacs_node = of_find_node_by_name(NULL, "awacs");
2567 if (awacs_node)
2568 awacs_revision = AWACS_AWACS;
2569
2570 /* powermac models after 9500 (other than those which use DACA or
2571 * Tumbler) have a node called "davbus".
2572 */
2573 np = of_find_node_by_name(NULL, "davbus");
2574 /*
2575 * if we didn't find a davbus device, try 'i2s-a' since
2576 * this seems to be what iBooks (& Tumbler) have.
2577 */
2578 if (np == NULL) {
2579 i2s_node = of_find_node_by_name(NULL, "i2s-a");
2580 np = of_node_get(i2s_node);
2581 }
2582
2583 /* if we didn't find this - perhaps we are on an early model
2584 * which _only_ has an 'awacs' node
2585 */
2586 if (np == NULL && awacs_node)
2587 np = of_node_get(awacs_node);
2588
2589 /* if we failed all these return null - this will cause the
2590 * driver to give up...
2591 */
2592 return np ;
2593}
2594
2595/* Get the OF node that contains the info about the sound chip, inputs s-rates
2596 etc.
2597 This node does not exist (or contains much reduced info) on earlier machines
2598 we have to deduce the info other ways for these.
2599*/
2600
2601static struct device_node* __init
2602get_snd_info_node(struct device_node *io)
2603{
2604 struct device_node *info;
2605
2606 for_each_node_by_name(info, "sound")
2607 if (info->parent == io)
2608 break;
2609 return info;
2610}
2611
2612/* Find out what type of codec we have.
2613*/
2614
2615static int __init
2616get_codec_type(struct device_node *info)
2617{
2618 /* already set if pre-davbus model and info will be NULL */
2619 int codec = awacs_revision ;
2620
2621 if (info) {
2622 /* must do awacs first to allow screamer to overide it */
2623 if (of_device_is_compatible(info, "awacs"))
2624 codec = AWACS_AWACS ;
2625 if (of_device_is_compatible(info, "screamer"))
2626 codec = AWACS_SCREAMER;
2627 if (of_device_is_compatible(info, "burgundy"))
2628 codec = AWACS_BURGUNDY ;
2629 if (of_device_is_compatible(info, "daca"))
2630 codec = AWACS_DACA;
2631 if (of_device_is_compatible(info, "tumbler"))
2632 codec = AWACS_TUMBLER;
2633 if (of_device_is_compatible(info, "snapper"))
2634 codec = AWACS_SNAPPER;
2635 }
2636 return codec ;
2637}
2638
2639/* find out what type, if any, of expansion card we have
2640*/
2641static void __init
2642get_expansion_type(void)
2643{
2644 struct device_node *dn;
2645
2646 dn = of_find_node_by_name(NULL, "perch");
2647 if (dn != NULL)
2648 has_perch = 1;
2649 of_node_put(dn);
2650
2651 dn = of_find_node_by_name(NULL, "pb-ziva-pc");
2652 if (dn != NULL)
2653 has_ziva = 1;
2654 of_node_put(dn);
2655 /* need to work out how we deal with iMac SRS module */
2656}
2657
2658/* set up frame rates.
2659 * I suspect that these routines don't quite go about it the right way:
2660 * - where there is more than one rate - I think that the first property
2661 * value is the number of rates.
2662 * TODO: check some more device trees and modify accordingly
2663 * Set dmasound.mach.max_dsp_rate on the basis of these routines.
2664*/
2665
2666static void __init
2667awacs_init_frame_rates(const unsigned int *prop, unsigned int l)
2668{
2669 int i ;
2670 if (prop) {
2671 for (i=0; i<8; i++)
2672 awacs_freqs_ok[i] = 0 ;
2673 for (l /= sizeof(int); l > 0; --l) {
2674 unsigned int r = *prop++;
2675 /* Apple 'Fixed' format */
2676 if (r >= 0x10000)
2677 r >>= 16;
2678 for (i = 0; i < 8; ++i) {
2679 if (r == awacs_freqs[i]) {
2680 awacs_freqs_ok[i] = 1;
2681 break;
2682 }
2683 }
2684 }
2685 }
2686 /* else we assume that all the rates are available */
2687}
2688
2689static void __init
2690burgundy_init_frame_rates(const unsigned int *prop, unsigned int l)
2691{
2692 int temp[9] ;
2693 int i = 0 ;
2694 if (prop) {
2695 for (l /= sizeof(int); l > 0; --l) {
2696 unsigned int r = *prop++;
2697 /* Apple 'Fixed' format */
2698 if (r >= 0x10000)
2699 r >>= 16;
2700 temp[i] = r ;
2701 i++ ; if(i>=9) i=8;
2702 }
2703 }
2704#ifdef DEBUG_DMASOUND
2705if (i > 1){
2706 int j;
2707 printk("dmasound_pmac: burgundy with multiple frame rates\n");
2708 for(j=0; j<i; j++)
2709 printk("%d ", temp[j]) ;
2710 printk("\n") ;
2711}
2712#endif
2713}
2714
2715static void __init
2716daca_init_frame_rates(const unsigned int *prop, unsigned int l)
2717{
2718 int temp[9] ;
2719 int i = 0 ;
2720 if (prop) {
2721 for (l /= sizeof(int); l > 0; --l) {
2722 unsigned int r = *prop++;
2723 /* Apple 'Fixed' format */
2724 if (r >= 0x10000)
2725 r >>= 16;
2726 temp[i] = r ;
2727 i++ ; if(i>=9) i=8;
2728
2729 }
2730 }
2731#ifdef DEBUG_DMASOUND
2732if (i > 1){
2733 int j;
2734 printk("dmasound_pmac: DACA with multiple frame rates\n");
2735 for(j=0; j<i; j++)
2736 printk("%d ", temp[j]) ;
2737 printk("\n") ;
2738}
2739#endif
2740}
2741
2742static void __init
2743init_frame_rates(const unsigned int *prop, unsigned int l)
2744{
2745 switch (awacs_revision) {
2746 case AWACS_TUMBLER:
2747 case AWACS_SNAPPER:
2748 tas_init_frame_rates(prop, l);
2749 break ;
2750 case AWACS_DACA:
2751 daca_init_frame_rates(prop, l);
2752 break ;
2753 case AWACS_BURGUNDY:
2754 burgundy_init_frame_rates(prop, l);
2755 break ;
2756 default:
2757 awacs_init_frame_rates(prop, l);
2758 break ;
2759 }
2760}
2761
2762/* find things/machines that can't do mac-io byteswap
2763*/
2764
2765static void __init
2766set_hw_byteswap(struct device_node *io)
2767{
2768 struct device_node *mio ;
2769 unsigned int kl = 0 ;
2770
2771 /* if seems that Keylargo can't byte-swap */
2772
2773 for (mio = io->parent; mio ; mio = mio->parent) {
2774 if (strcmp(mio->name, "mac-io") == 0) {
2775 if (of_device_is_compatible(mio, "Keylargo"))
2776 kl = 1;
2777 break;
2778 }
2779 }
2780 hw_can_byteswap = !kl;
2781}
2782
2783/* Allocate the resources necessary for beep generation. This cannot be (quite)
2784 done statically (yet) because we cannot do virt_to_bus() on static vars when
2785 the code is loaded as a module.
2786
2787 for the sake of saving the possibility that two allocations will incur the
2788 overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma
2789 command here as well... even tho' it is not part of the beep process.
2790*/
2791
2792int32_t
2793__init setup_beep(void)
2794{
2795 /* Initialize beep stuff */
2796 /* want one cmd buffer for beeps, and a second one for emergencies
2797 - i.e. dbdma error conditions.
2798 ask for three to allow for pull up in DBDMA_ALIGN().
2799 */
2800 beep_dbdma_cmd_space =
2801 kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL);
2802 if(beep_dbdma_cmd_space == NULL) {
2803 printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ;
2804 return -ENOMEM ;
2805 }
2806 beep_dbdma_cmd = (volatile struct dbdma_cmd *)
2807 DBDMA_ALIGN(beep_dbdma_cmd_space);
2808 /* set up emergency dbdma cmd */
2809 emergency_dbdma_cmd = beep_dbdma_cmd+1 ;
2810 beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
2811 if (beep_buf == NULL) {
2812 printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
2813 kfree(beep_dbdma_cmd_space) ;
2814 return -ENOMEM ;
2815 }
2816 return 0 ;
2817}
2818
2819static struct input_dev *awacs_beep_dev;
2820
2821int __init dmasound_awacs_init(void)
2822{
2823 struct device_node *io = NULL, *info = NULL;
2824 int vol, res;
2825
2826 if (!machine_is(powermac))
2827 return -ENODEV;
2828
2829 awacs_subframe = 0;
2830 awacs_revision = 0;
2831 hw_can_byteswap = 1 ; /* most can */
2832
2833 /* look for models we need to handle specially */
2834 set_model() ;
2835
2836 /* find the OF node that tells us about the dbdma stuff
2837 */
2838 io = get_snd_io_node();
2839 if (io == NULL) {
2840#ifdef DEBUG_DMASOUND
2841printk("dmasound_pmac: couldn't find sound io OF node\n");
2842#endif
2843 goto no_device;
2844 }
2845
2846 /* find the OF node that tells us about the sound sub-system
2847 * this doesn't exist on pre-davbus machines (earlier than 9500)
2848 */
2849 if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */
2850 info = get_snd_info_node(io) ;
2851 if (info == NULL){
2852#ifdef DEBUG_DMASOUND
2853printk("dmasound_pmac: couldn't find 'sound' OF node\n");
2854#endif
2855 goto no_device;
2856 }
2857 }
2858
2859 awacs_revision = get_codec_type(info) ;
2860 if (awacs_revision == 0) {
2861#ifdef DEBUG_DMASOUND
2862printk("dmasound_pmac: couldn't find a Codec we can handle\n");
2863#endif
2864 goto no_device; /* we don't know this type of h/w */
2865 }
2866
2867 /* set up perch, ziva, SRS or whatever else we have as sound
2868 * expansion.
2869 */
2870 get_expansion_type();
2871
2872 /* we've now got enough information to make up the audio topology.
2873 * we will map the sound part of mac-io now so that we can probe for
2874 * other info if necessary (early AWACS we want to read chip ids)
2875 */
2876
2877 if (of_get_address(io, 2, NULL, NULL) == NULL) {
2878 /* OK - maybe we need to use the 'awacs' node (on earlier
2879 * machines).
2880 */
2881 if (awacs_node) {
2882 of_node_put(io);
2883 io = of_node_get(awacs_node);
2884 if (of_get_address(io, 2, NULL, NULL) == NULL) {
2885 printk("dmasound_pmac: can't use %s\n",
2886 io->full_name);
2887 goto no_device;
2888 }
2889 } else
2890 printk("dmasound_pmac: can't use %s\n", io->full_name);
2891 }
2892
2893 if (of_address_to_resource(io, 0, &awacs_rsrc[0]) ||
2894 request_mem_region(awacs_rsrc[0].start,
2895 awacs_rsrc[0].end - awacs_rsrc[0].start + 1,
2896 " (IO)") == NULL) {
2897 printk(KERN_ERR "dmasound: can't request IO resource !\n");
2898 goto no_device;
2899 }
2900 if (of_address_to_resource(io, 1, &awacs_rsrc[1]) ||
2901 request_mem_region(awacs_rsrc[1].start,
2902 awacs_rsrc[1].end - awacs_rsrc[1].start + 1,
2903 " (tx dma)") == NULL) {
2904 release_mem_region(awacs_rsrc[0].start,
2905 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
2906 printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n");
2907 goto no_device;
2908 }
2909 if (of_address_to_resource(io, 2, &awacs_rsrc[2]) ||
2910 request_mem_region(awacs_rsrc[2].start,
2911 awacs_rsrc[2].end - awacs_rsrc[2].start + 1,
2912 " (rx dma)") == NULL) {
2913 release_mem_region(awacs_rsrc[0].start,
2914 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
2915 release_mem_region(awacs_rsrc[1].start,
2916 awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
2917 printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n");
2918 goto no_device;
2919 }
2920
2921 awacs_beep_dev = input_allocate_device();
2922 if (!awacs_beep_dev) {
2923 release_mem_region(awacs_rsrc[0].start,
2924 awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
2925 release_mem_region(awacs_rsrc[1].start,
2926 awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
2927 release_mem_region(awacs_rsrc[2].start,
2928 awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
2929 printk(KERN_ERR "dmasound: can't allocate input device !\n");
2930 goto no_device;
2931 }
2932
2933 awacs_beep_dev->name = "dmasound beeper";
2934 awacs_beep_dev->phys = "macio/input0";
2935 awacs_beep_dev->id.bustype = BUS_HOST;
2936 awacs_beep_dev->event = awacs_beep_event;
2937 awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
2938 awacs_beep_dev->evbit[0] = BIT(EV_SND);
2939
2940 /* all OF versions I've seen use this value */
2941 if (i2s_node)
2942 i2s = ioremap(awacs_rsrc[0].start, 0x1000);
2943 else
2944 awacs = ioremap(awacs_rsrc[0].start, 0x1000);
2945 awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100);
2946 awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100);
2947
2948 /* first of all make sure that the chip is powered up....*/
2949 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
2950 if (awacs_revision == AWACS_SCREAMER && awacs)
2951 awacs_recalibrate();
2952
2953 awacs_irq = irq_of_parse_and_map(io, 0);
2954 awacs_tx_irq = irq_of_parse_and_map(io, 1);
2955 awacs_rx_irq = irq_of_parse_and_map(io, 2);
2956
2957 /* Hack for legacy crap that will be killed someday */
2958 of_node_put(awacs_node);
2959 awacs_node = of_node_get(io);
2960
2961 /* if we have an awacs or screamer - probe the chip to make
2962 * sure we have the right revision.
2963 */
2964
2965 if (awacs_revision <= AWACS_SCREAMER){
2966 uint32_t temp, rev, mfg ;
2967 /* find out the awacs revision from the chip */
2968 temp = in_le32(&awacs->codec_stat);
2969 rev = (temp >> 12) & 0xf;
2970 mfg = (temp >> 8) & 0xf;
2971#ifdef DEBUG_DMASOUND
2972printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
2973#endif
2974 if (rev >= AWACS_SCREAMER)
2975 awacs_revision = AWACS_SCREAMER ;
2976 else
2977 awacs_revision = rev ;
2978 }
2979
2980 dmasound.mach = machPMac;
2981
2982 /* find out other bits & pieces from OF, these may be present
2983 only on some models ... so be careful.
2984 */
2985
2986 /* in the absence of a frame rates property we will use the defaults
2987 */
2988
2989 if (info) {
2990 const unsigned int *prop;
2991 unsigned int l;
2992
2993 sound_device_id = 0;
2994 /* device ID appears post g3 b&w */
2995 prop = of_get_property(info, "device-id", NULL);
2996 if (prop != 0)
2997 sound_device_id = *prop;
2998
2999 /* look for a property saying what sample rates
3000 are available */
3001
3002 prop = of_get_property(info, "sample-rates", &l);
3003 if (prop == 0)
3004 prop = of_get_property(info, "output-frame-rates", &l);
3005
3006 /* if it's there use it to set up frame rates */
3007 init_frame_rates(prop, l) ;
3008 of_node_put(info);
3009 info = NULL;
3010 }
3011
3012 if (awacs)
3013 out_le32(&awacs->control, 0x11); /* set everything quiesent */
3014
3015 set_hw_byteswap(io) ; /* figure out if the h/w can do it */
3016
3017#ifdef CONFIG_NVRAM
3018 /* get default volume from nvram */
3019 vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
3020#else
3021 vol = 0;
3022#endif
3023
3024 /* set up tracking values */
3025 spk_vol = vol * 100 ;
3026 spk_vol /= 7 ; /* get set value to a percentage */
3027 spk_vol |= (spk_vol << 8) ; /* equal left & right */
3028 line_vol = passthru_vol = spk_vol ;
3029
3030 /* fill regs that are shared between AWACS & Burgundy */
3031
3032 awacs_reg[2] = vol + (vol << 6);
3033 awacs_reg[4] = vol + (vol << 6);
3034 awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */
3035 awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */
3036 awacs_reg[7] = 0;
3037
3038 awacs_reg[0] = MASK_MUX_CD;
3039 awacs_reg[1] = MASK_LOOPTHRU;
3040
3041 /* FIXME: Only machines with external SRS module need MASK_PAROUT */
3042 if (has_perch || sound_device_id == 0x5
3043 || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb)
3044 awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
3045
3046 switch (awacs_revision) {
3047 case AWACS_TUMBLER:
3048 tas_register_driver(&tas3001c_hooks);
3049 tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
3050 tas_dmasound_init();
3051 tas_post_init();
3052 break ;
3053 case AWACS_SNAPPER:
3054 tas_register_driver(&tas3004_hooks);
3055 tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
3056 tas_dmasound_init();
3057 tas_post_init();
3058 break;
3059 case AWACS_DACA:
3060 daca_init();
3061 break;
3062 case AWACS_BURGUNDY:
3063 awacs_burgundy_init();
3064 break ;
3065 case AWACS_SCREAMER:
3066 case AWACS_AWACS:
3067 default:
3068 load_awacs();
3069 break ;
3070 }
3071
3072 /* enable/set-up external modules - when we know how */
3073
3074 if (has_perch)
3075 awacs_enable_amp(100 * 0x101);
3076
3077 /* Reset dbdma channels */
3078 out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
3079 while (in_le32(&awacs_txdma->status) & RUN)
3080 udelay(1);
3081 out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
3082 while (in_le32(&awacs_rxdma->status) & RUN)
3083 udelay(1);
3084
3085 /* Initialize beep stuff */
3086 if ((res=setup_beep()))
3087 return res ;
3088
3089#ifdef CONFIG_PM
3090 pmu_register_sleep_notifier(&awacs_sleep_notifier);
3091#endif /* CONFIG_PM */
3092
3093 /* Powerbooks have odd ways of enabling inputs such as
3094 an expansion-bay CD or sound from an internal modem
3095 or a PC-card modem. */
3096 if (is_pbook_3X00) {
3097 /*
3098 * Enable CD and PC-card sound inputs.
3099 * This is done by reading from address
3100 * f301a000, + 0x10 to enable the expansion-bay
3101 * CD sound input, + 0x80 to enable the PC-card
3102 * sound input. The 0x100 enables the SCSI bus
3103 * terminator power.
3104 */
3105 latch_base = ioremap (0xf301a000, 0x1000);
3106 in_8(latch_base + 0x190);
3107
3108 } else if (is_pbook_g3) {
3109 struct device_node* mio;
3110 macio_base = NULL;
3111 for (mio = io->parent; mio; mio = mio->parent) {
3112 if (strcmp(mio->name, "mac-io") == 0) {
3113 struct resource r;
3114 if (of_address_to_resource(mio, 0, &r) == 0)
3115 macio_base = ioremap(r.start, 0x40);
3116 break;
3117 }
3118 }
3119 /*
3120 * Enable CD sound input.
3121 * The relevant bits for writing to this byte are 0x8f.
3122 * I haven't found out what the 0x80 bit does.
3123 * For the 0xf bits, writing 3 or 7 enables the CD
3124 * input, any other value disables it. Values
3125 * 1, 3, 5, 7 enable the microphone. Values 0, 2,
3126 * 4, 6, 8 - f enable the input from the modem.
3127 * -- paulus.
3128 */
3129 if (macio_base)
3130 out_8(macio_base + 0x37, 3);
3131 }
3132
3133 if (hw_can_byteswap)
3134 dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ;
3135 else
3136 dmasound.mach.hardware_afmts = AFMT_S16_BE ;
3137
3138 /* shut out chips that do output only.
3139 * may need to extend this to machines which have no inputs - even tho'
3140 * they use screamer - IIRC one of the powerbooks is like this.
3141 */
3142
3143 if (awacs_revision != AWACS_DACA) {
3144 dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
3145 dmasound.mach.record = PMacRecord ;
3146 }
3147
3148 dmasound.mach.default_hard = def_hard ;
3149 dmasound.mach.default_soft = def_soft ;
3150
3151 switch (awacs_revision) {
3152 case AWACS_BURGUNDY:
3153 sprintf(awacs_name, "PowerMac Burgundy ") ;
3154 break ;
3155 case AWACS_DACA:
3156 sprintf(awacs_name, "PowerMac DACA ") ;
3157 break ;
3158 case AWACS_TUMBLER:
3159 sprintf(awacs_name, "PowerMac Tumbler ") ;
3160 break ;
3161 case AWACS_SNAPPER:
3162 sprintf(awacs_name, "PowerMac Snapper ") ;
3163 break ;
3164 case AWACS_SCREAMER:
3165 sprintf(awacs_name, "PowerMac Screamer ") ;
3166 break ;
3167 case AWACS_AWACS:
3168 default:
3169 sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ;
3170 break ;
3171 }
3172
3173 /*
3174 * XXX: we should handle errors here, but that would mean
3175 * rewriting the whole init code. later..
3176 */
3177 input_register_device(awacs_beep_dev);
3178
3179 of_node_put(io);
3180
3181 return dmasound_init();
3182
3183no_device:
3184 of_node_put(info);
3185 of_node_put(awacs_node);
3186 of_node_put(i2s_node);
3187 of_node_put(io);
3188 return -ENODEV ;
3189}
3190
3191static void __exit dmasound_awacs_cleanup(void)
3192{
3193 input_unregister_device(awacs_beep_dev);
3194
3195 switch (awacs_revision) {
3196 case AWACS_TUMBLER:
3197 case AWACS_SNAPPER:
3198 tas_dmasound_cleanup();
3199 tas_cleanup();
3200 break ;
3201 case AWACS_DACA:
3202 daca_cleanup();
3203 break;
3204 }
3205 dmasound_deinit();
3206
3207 of_node_put(awacs_node);
3208 of_node_put(i2s_node);
3209}
3210
3211MODULE_DESCRIPTION("PowerMac built-in audio driver.");
3212MODULE_LICENSE("GPL");
3213
3214module_init(dmasound_awacs_init);
3215module_exit(dmasound_awacs_cleanup);
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index f4056a9c371b..a003c0ea9303 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -202,13 +202,6 @@ module_param(numWriteBufs, int, 0);
202static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ 202static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */
203module_param(writeBufSize, int, 0); 203module_param(writeBufSize, int, 0);
204 204
205#ifdef HAS_RECORD
206static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
207module_param(numReadBufs, int, 0);
208static unsigned int readBufSize = DEFAULT_BUFF_SIZE; /* in bytes */
209module_param(readBufSize, int, 0);
210#endif
211
212MODULE_LICENSE("GPL"); 205MODULE_LICENSE("GPL");
213 206
214#ifdef MODULE 207#ifdef MODULE
@@ -403,10 +396,6 @@ static void mixer_init(void)
403 396
404struct sound_queue dmasound_write_sq; 397struct sound_queue dmasound_write_sq;
405static void sq_reset_output(void) ; 398static void sq_reset_output(void) ;
406#ifdef HAS_RECORD
407struct sound_queue dmasound_read_sq;
408static void sq_reset_input(void) ;
409#endif
410 399
411static int sq_allocate_buffers(struct sound_queue *sq, int num, int size) 400static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
412{ 401{
@@ -530,12 +519,6 @@ printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
530 sq->rear = -1; 519 sq->rear = -1;
531 setup_func = dmasound.mach.write_sq_setup; 520 setup_func = dmasound.mach.write_sq_setup;
532 } 521 }
533#ifdef HAS_RECORD
534 else {
535 sq->rear = 0;
536 setup_func = dmasound.mach.read_sq_setup;
537 }
538#endif
539 if (setup_func) 522 if (setup_func)
540 return setup_func(); 523 return setup_func();
541 return 0 ; 524 return 0 ;
@@ -672,13 +655,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
672 } 655 }
673 if (file->f_mode & FMODE_WRITE ) 656 if (file->f_mode & FMODE_WRITE )
674 poll_wait(file, &write_sq.action_queue, wait); 657 poll_wait(file, &write_sq.action_queue, wait);
675#ifdef HAS_RECORD
676 if (file->f_mode & FMODE_READ)
677 poll_wait(file, &read_sq.action_queue, wait);
678 if (file->f_mode & FMODE_READ)
679 if (read_sq.block_size - read_sq.rear_size > 0)
680 mask |= POLLIN | POLLRDNORM;
681#endif
682 if (file->f_mode & FMODE_WRITE) 658 if (file->f_mode & FMODE_WRITE)
683 if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0) 659 if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
684 mask |= POLLOUT | POLLWRNORM; 660 mask |= POLLOUT | POLLWRNORM;
@@ -686,101 +662,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
686 662
687} 663}
688 664
689#ifdef HAS_RECORD
690 /*
691 * Here is how the values are used for reading.
692 * The value 'active' simply indicates the DMA is running. This is done
693 * so the driver semantics are DMA starts when the first read is posted.
694 * The value 'front' indicates the buffer we should next send to the user.
695 * The value 'rear' indicates the buffer the DMA is currently filling.
696 * When 'front' == 'rear' the buffer "ring" is empty (we always have an
697 * empty available). The 'rear_size' is used to track partial offsets
698 * into the buffer we are currently returning to the user.
699
700 * This level (> [1.5]) doesn't care what strategy the LL driver uses with
701 * DMA on over-run. It can leave it running (and keep active == 1) or it
702 * can kill it and set active == 0 in which case this routine will spot
703 * it and restart the DMA.
704 */
705
706static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft,
707 loff_t *ppos)
708{
709
710 ssize_t uRead, bLeft, bUsed, uUsed;
711
712 if (uLeft == 0)
713 return 0;
714
715 /* cater for the compatibility mode - record compiled in but no LL */
716 if (dmasound.mach.record == NULL)
717 return -EINVAL ;
718
719 /* see comment in sq_write()
720 */
721
722 if( shared_resources_initialised == 0) {
723 dmasound.mach.init() ;
724 shared_resources_initialised = 1 ;
725 }
726
727 /* set up the sq if it is not already done. see comments in sq_write().
728 */
729
730 if (read_sq.locked == 0) {
731 if ((uRead = sq_setup(&read_sq)) < 0)
732 return uRead ;
733 }
734
735 uRead = 0;
736
737 /* Move what the user requests, depending upon other options.
738 */
739 while (uLeft > 0) {
740
741 /* we happened to get behind and the LL driver killed DMA
742 then we should set it going again. This also sets it
743 going the first time through.
744 */
745 if ( !read_sq.active )
746 dmasound.mach.record();
747
748 /* When front == rear, the DMA is not done yet.
749 */
750 while (read_sq.front == read_sq.rear) {
751 if (read_sq.open_mode & O_NONBLOCK) {
752 return uRead > 0 ? uRead : -EAGAIN;
753 }
754 SLEEP(read_sq.action_queue);
755 if (signal_pending(current))
756 return uRead > 0 ? uRead : -EINTR;
757 }
758
759 /* The amount we move is either what is left in the
760 * current buffer or what the user wants.
761 */
762 bLeft = read_sq.block_size - read_sq.rear_size;
763 bUsed = read_sq.rear_size;
764 uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
765 read_sq.buffers[read_sq.front],
766 &bUsed, bLeft);
767 if (uUsed <= 0)
768 return uUsed;
769 dst += uUsed;
770 uRead += uUsed;
771 uLeft -= uUsed;
772 read_sq.rear_size += bUsed;
773 if (read_sq.rear_size >= read_sq.block_size) {
774 read_sq.rear_size = 0;
775 read_sq.front++;
776 if (read_sq.front >= read_sq.max_active)
777 read_sq.front = 0;
778 }
779 }
780 return uRead;
781}
782#endif /* HAS_RECORD */
783
784static inline void sq_init_waitqueue(struct sound_queue *sq) 665static inline void sq_init_waitqueue(struct sound_queue *sq)
785{ 666{
786 init_waitqueue_head(&sq->action_queue); 667 init_waitqueue_head(&sq->action_queue);
@@ -854,23 +735,6 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
854#define write_sq_open(file) \ 735#define write_sq_open(file) \
855 sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize ) 736 sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
856 737
857#ifdef HAS_RECORD
858#define read_sq_init_waitqueue() sq_init_waitqueue(&read_sq)
859#if 0 /* blocking open() */
860#define read_sq_wake_up(file) sq_wake_up(&read_sq, file, FMODE_READ)
861#endif
862#define read_sq_release_buffers() sq_release_buffers(&read_sq)
863#define read_sq_open(file) \
864 sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
865#else
866#define read_sq_init_waitqueue() do {} while (0)
867#if 0 /* blocking open() */
868#define read_sq_wake_up(file) do {} while (0)
869#endif
870#define read_sq_release_buffers() do {} while (0)
871#define sq_reset_input() do {} while (0)
872#endif
873
874static int sq_open(struct inode *inode, struct file *file) 738static int sq_open(struct inode *inode, struct file *file)
875{ 739{
876 int rc; 740 int rc;
@@ -881,25 +745,11 @@ static int sq_open(struct inode *inode, struct file *file)
881 rc = write_sq_open(file); /* checks the f_mode */ 745 rc = write_sq_open(file); /* checks the f_mode */
882 if (rc) 746 if (rc)
883 goto out; 747 goto out;
884#ifdef HAS_RECORD
885 if (dmasound.mach.record) {
886 rc = read_sq_open(file); /* checks the f_mode */
887 if (rc)
888 goto out;
889 } else { /* no record function installed; in compat mode */
890 if (file->f_mode & FMODE_READ) {
891 /* TODO: if O_RDWR, release any resources grabbed by write part */
892 rc = -ENXIO;
893 goto out;
894 }
895 }
896#else /* !HAS_RECORD */
897 if (file->f_mode & FMODE_READ) { 748 if (file->f_mode & FMODE_READ) {
898 /* TODO: if O_RDWR, release any resources grabbed by write part */ 749 /* TODO: if O_RDWR, release any resources grabbed by write part */
899 rc = -ENXIO ; /* I think this is what is required by open(2) */ 750 rc = -ENXIO ; /* I think this is what is required by open(2) */
900 goto out; 751 goto out;
901 } 752 }
902#endif /* HAS_RECORD */
903 753
904 if (dmasound.mach.sq_open) 754 if (dmasound.mach.sq_open)
905 dmasound.mach.sq_open(file->f_mode); 755 dmasound.mach.sq_open(file->f_mode);
@@ -956,43 +806,9 @@ static void sq_reset_output(void)
956 write_sq.user_frag_size = 0 ; 806 write_sq.user_frag_size = 0 ;
957} 807}
958 808
959#ifdef HAS_RECORD
960
961static void sq_reset_input(void)
962{
963 if (dmasound.mach.record && read_sq.active) {
964 if (dmasound.mach.abort_read) { /* this routine must really be present */
965 read_sq.syncing = 1 ;
966 /* this can use the read_sq.sync_queue to sleep if
967 necessary - it should not return until DMA
968 is really stopped - because we might deallocate
969 the buffers as the next action...
970 */
971 dmasound.mach.abort_read() ;
972 } else {
973 printk(KERN_ERR
974 "dmasound_core: %s has no abort_read()!! all bets are off\n",
975 dmasound.mach.name) ;
976 }
977 }
978 read_sq.syncing =
979 read_sq.active =
980 read_sq.front =
981 read_sq.count =
982 read_sq.rear = 0 ;
983
984 /* OK - we can unlock the parameters and fragment settings */
985 read_sq.locked = 0 ;
986 read_sq.user_frags = 0 ;
987 read_sq.user_frag_size = 0 ;
988}
989
990#endif
991
992static void sq_reset(void) 809static void sq_reset(void)
993{ 810{
994 sq_reset_output() ; 811 sq_reset_output() ;
995 sq_reset_input() ;
996 /* we could consider resetting the shared_resources_owner here... but I 812 /* we could consider resetting the shared_resources_owner here... but I
997 think it is probably still rather non-obvious to application writer 813 think it is probably still rather non-obvious to application writer
998 */ 814 */
@@ -1038,17 +854,6 @@ static int sq_release(struct inode *inode, struct file *file)
1038 854
1039 lock_kernel(); 855 lock_kernel();
1040 856
1041#ifdef HAS_RECORD
1042 /* probably best to do the read side first - so that time taken to do it
1043 overlaps with playing any remaining output samples.
1044 */
1045 if (file->f_mode & FMODE_READ) {
1046 sq_reset_input() ; /* make sure dma is stopped and all is quiet */
1047 read_sq_release_buffers();
1048 read_sq.busy = 0;
1049 }
1050#endif
1051
1052 if (file->f_mode & FMODE_WRITE) { 857 if (file->f_mode & FMODE_WRITE) {
1053 if (write_sq.busy) 858 if (write_sq.busy)
1054 rc = sq_fsync(file, file->f_path.dentry); 859 rc = sq_fsync(file, file->f_path.dentry);
@@ -1105,11 +910,6 @@ static int shared_resources_are_mine(mode_t md)
1105 910
1106static int queues_are_quiescent(void) 911static int queues_are_quiescent(void)
1107{ 912{
1108#ifdef HAS_RECORD
1109 if (dmasound.mach.record)
1110 if (read_sq.locked)
1111 return 0 ;
1112#endif
1113 if (write_sq.locked) 913 if (write_sq.locked)
1114 return 0 ; 914 return 0 ;
1115 return 1 ; 915 return 1 ;
@@ -1185,13 +985,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
1185 the read_sq ones. 985 the read_sq ones.
1186 */ 986 */
1187 size = 0 ; 987 size = 0 ;
1188#ifdef HAS_RECORD
1189 if (dmasound.mach.record && (file->f_mode & FMODE_READ)) {
1190 if ( !read_sq.locked )
1191 sq_setup(&read_sq) ; /* set params */
1192 size = read_sq.user_frag_size ;
1193 }
1194#endif
1195 if (file->f_mode & FMODE_WRITE) { 988 if (file->f_mode & FMODE_WRITE) {
1196 if ( !write_sq.locked ) 989 if ( !write_sq.locked )
1197 sq_setup(&write_sq) ; 990 sq_setup(&write_sq) ;
@@ -1214,8 +1007,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
1214 everything - read, however, is killed imediately. 1007 everything - read, however, is killed imediately.
1215 */ 1008 */
1216 result = 0 ; 1009 result = 0 ;
1217 if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
1218 sq_reset_input() ;
1219 if (file->f_mode & FMODE_WRITE) { 1010 if (file->f_mode & FMODE_WRITE) {
1220 result = sq_fsync(file, file->f_path.dentry); 1011 result = sq_fsync(file, file->f_path.dentry);
1221 sq_reset_output() ; 1012 sq_reset_output() ;
@@ -1294,13 +1085,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
1294 result = 0 ; 1085 result = 0 ;
1295 nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */ 1086 nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
1296 size = data & 0xffff; 1087 size = data & 0xffff;
1297#ifdef HAS_RECORD
1298 if ((file->f_mode & FMODE_READ) && dmasound.mach.record) {
1299 result = set_queue_frags(&read_sq, nbufs, size) ;
1300 if (result)
1301 return result ;
1302 }
1303#endif
1304 if (file->f_mode & FMODE_WRITE) { 1088 if (file->f_mode & FMODE_WRITE) {
1305 result = set_queue_frags(&write_sq, nbufs, size) ; 1089 result = set_queue_frags(&write_sq, nbufs, size) ;
1306 if (result) 1090 if (result)
@@ -1348,20 +1132,6 @@ static const struct file_operations sq_fops =
1348 .release = sq_release, 1132 .release = sq_release,
1349}; 1133};
1350 1134
1351#ifdef HAS_RECORD
1352static const struct file_operations sq_fops_record =
1353{
1354 .owner = THIS_MODULE,
1355 .llseek = no_llseek,
1356 .write = sq_write,
1357 .poll = sq_poll,
1358 .ioctl = sq_ioctl,
1359 .open = sq_open,
1360 .release = sq_release,
1361 .read = sq_read,
1362};
1363#endif
1364
1365static int sq_init(void) 1135static int sq_init(void)
1366{ 1136{
1367 const struct file_operations *fops = &sq_fops; 1137 const struct file_operations *fops = &sq_fops;
@@ -1369,10 +1139,6 @@ static int sq_init(void)
1369 int sq_unit; 1139 int sq_unit;
1370#endif 1140#endif
1371 1141
1372#ifdef HAS_RECORD
1373 if (dmasound.mach.record)
1374 fops = &sq_fops_record;
1375#endif
1376 sq_unit = register_sound_dsp(fops, -1); 1142 sq_unit = register_sound_dsp(fops, -1);
1377 if (sq_unit < 0) { 1143 if (sq_unit < 0) {
1378 printk(KERN_ERR "dmasound_core: couldn't register fops\n") ; 1144 printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
@@ -1380,7 +1146,6 @@ static int sq_init(void)
1380 } 1146 }
1381 1147
1382 write_sq_init_waitqueue(); 1148 write_sq_init_waitqueue();
1383 read_sq_init_waitqueue();
1384 1149
1385 /* These parameters will be restored for every clean open() 1150 /* These parameters will be restored for every clean open()
1386 * in the case of multiple open()s (e.g. dsp0 & dsp1) they 1151 * in the case of multiple open()s (e.g. dsp0 & dsp1) they
@@ -1406,11 +1171,7 @@ static int sq_init(void)
1406 driver. 1171 driver.
1407*/ 1172*/
1408 1173
1409#ifdef HAS_RECORD
1410#define STAT_BUFF_LEN 1024
1411#else
1412#define STAT_BUFF_LEN 768 1174#define STAT_BUFF_LEN 768
1413#endif
1414 1175
1415/* this is how much space we will allow the low-level driver to use 1176/* this is how much space we will allow the low-level driver to use
1416 in the stat buffer. Currently, 2 * (80 character line + <NL>). 1177 in the stat buffer. Currently, 2 * (80 character line + <NL>).
@@ -1518,11 +1279,6 @@ static int state_open(struct inode *inode, struct file *file)
1518 len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ; 1279 len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
1519 len += sprintf(buffer+len,"%9s:%8d%6d\n", 1280 len += sprintf(buffer+len,"%9s:%8d%6d\n",
1520 "write", write_sq.numBufs, write_sq.bufSize) ; 1281 "write", write_sq.numBufs, write_sq.bufSize) ;
1521#ifdef HAS_RECORD
1522 if (dmasound.mach.record)
1523 len += sprintf(buffer+len,"%9s:%8d%6d\n",
1524 "read", read_sq.numBufs, read_sq.bufSize) ;
1525#endif
1526 len += sprintf(buffer+len, 1282 len += sprintf(buffer+len,
1527 "Current : MaxFrg FragSiz MaxAct Frnt Rear " 1283 "Current : MaxFrg FragSiz MaxAct Frnt Rear "
1528 "Cnt RrSize A B S L xruns\n") ; 1284 "Cnt RrSize A B S L xruns\n") ;
@@ -1531,14 +1287,6 @@ static int state_open(struct inode *inode, struct file *file)
1531 write_sq.max_active, write_sq.front, write_sq.rear, 1287 write_sq.max_active, write_sq.front, write_sq.rear,
1532 write_sq.count, write_sq.rear_size, write_sq.active, 1288 write_sq.count, write_sq.rear_size, write_sq.active,
1533 write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ; 1289 write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
1534#ifdef HAS_RECORD
1535 if (dmasound.mach.record)
1536 len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
1537 "read", read_sq.max_count, read_sq.block_size,
1538 read_sq.max_active, read_sq.front, read_sq.rear,
1539 read_sq.count, read_sq.rear_size, read_sq.active,
1540 read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;
1541#endif
1542#ifdef DEBUG_DMASOUND 1290#ifdef DEBUG_DMASOUND
1543printk("dmasound: stat buffer used %d bytes\n", len) ; 1291printk("dmasound: stat buffer used %d bytes\n", len) ;
1544#endif 1292#endif
@@ -1638,13 +1386,6 @@ int dmasound_init(void)
1638 (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ; 1386 (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
1639 printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n", 1387 printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
1640 numWriteBufs, writeBufSize) ; 1388 numWriteBufs, writeBufSize) ;
1641#ifdef HAS_RECORD
1642 if (dmasound.mach.record)
1643 printk(KERN_INFO
1644 "Read will use %4d fragments of %7d bytes as default\n",
1645 numReadBufs, readBufSize) ;
1646#endif
1647
1648 return 0; 1389 return 0;
1649} 1390}
1650 1391
@@ -1659,7 +1400,6 @@ void dmasound_deinit(void)
1659 } 1400 }
1660 1401
1661 write_sq_release_buffers(); 1402 write_sq_release_buffers();
1662 read_sq_release_buffers();
1663 1403
1664 if (mixer_unit >= 0) 1404 if (mixer_unit >= 0)
1665 unregister_sound_mixer(mixer_unit); 1405 unregister_sound_mixer(mixer_unit);
@@ -1684,36 +1424,12 @@ static int dmasound_setup(char *str)
1684 */ 1424 */
1685 1425
1686 switch (ints[0]) { 1426 switch (ints[0]) {
1687#ifdef HAS_RECORD
1688 case 5:
1689 if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
1690 printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
1691 else
1692 catchRadius = ints[5];
1693 /* fall through */
1694 case 4:
1695 if (ints[4] < MIN_BUFFERS)
1696 printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
1697 numReadBufs);
1698 else
1699 numReadBufs = ints[4];
1700 /* fall through */
1701 case 3:
1702 if ((size = ints[3]) < 256) /* check for small buffer specs */
1703 size <<= 10 ;
1704 if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
1705 printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
1706 else
1707 readBufSize = size;
1708 /* fall through */
1709#else
1710 case 3: 1427 case 3:
1711 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS)) 1428 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
1712 printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); 1429 printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
1713 else 1430 else
1714 catchRadius = ints[3]; 1431 catchRadius = ints[3];
1715 /* fall through */ 1432 /* fall through */
1716#endif
1717 case 2: 1433 case 2:
1718 if (ints[1] < MIN_BUFFERS) 1434 if (ints[1] < MIN_BUFFERS)
1719 printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs); 1435 printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
@@ -1830,9 +1546,6 @@ EXPORT_SYMBOL(dmasound_init);
1830EXPORT_SYMBOL(dmasound_deinit); 1546EXPORT_SYMBOL(dmasound_deinit);
1831#endif 1547#endif
1832EXPORT_SYMBOL(dmasound_write_sq); 1548EXPORT_SYMBOL(dmasound_write_sq);
1833#ifdef HAS_RECORD
1834EXPORT_SYMBOL(dmasound_read_sq);
1835#endif
1836EXPORT_SYMBOL(dmasound_catchRadius); 1549EXPORT_SYMBOL(dmasound_catchRadius);
1837#ifdef HAS_8BIT_TABLES 1550#ifdef HAS_8BIT_TABLES
1838EXPORT_SYMBOL(dmasound_ulaw2dma8); 1551EXPORT_SYMBOL(dmasound_ulaw2dma8);
diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c
deleted file mode 100644
index 4b7dbdd2a438..000000000000
--- a/sound/oss/dmasound/tas3001c.c
+++ /dev/null
@@ -1,849 +0,0 @@
1/*
2 * Driver for the i2c/i2s based TA3004 sound chip used
3 * on some Apple hardware. Also known as "snapper".
4 *
5 * Tobias Sargeant <tobias.sargeant@bigpond.com>
6 * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
7 *
8 * TODO:
9 * -----
10 * * Enable control over input line 2 (is this connected?)
11 * * Implement sleep support (at least mute everything and
12 * * set gains to minimum during sleep)
13 * * Look into some of Darwin's tweaks regarding the mute
14 * * lines (delays & different behaviour on some HW)
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/proc_fs.h>
21#include <linux/ioport.h>
22#include <linux/sysctl.h>
23#include <linux/types.h>
24#include <linux/i2c.h>
25#include <linux/init.h>
26#include <linux/soundcard.h>
27#include <linux/workqueue.h>
28#include <asm/uaccess.h>
29#include <asm/errno.h>
30#include <asm/io.h>
31#include <asm/prom.h>
32
33#include "dmasound.h"
34#include "tas_common.h"
35#include "tas3001c.h"
36
37#include "tas_ioctl.h"
38
39#define TAS3001C_BIQUAD_FILTER_COUNT 6
40#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
41
42#define VOL_DEFAULT (100 * 4 / 5)
43#define INPUT_DEFAULT (100 * 4 / 5)
44#define BASS_DEFAULT (100 / 2)
45#define TREBLE_DEFAULT (100 / 2)
46
47struct tas3001c_data_t {
48 struct tas_data_t super;
49 int device_id;
50 int output_id;
51 int speaker_id;
52 struct tas_drce_t drce_state;
53 struct work_struct change;
54};
55
56
57static const union tas_biquad_t
58tas3001c_eq_unity={
59 .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
60};
61
62
63static inline unsigned char db_to_regval(short db) {
64 int r=0;
65
66 r=(db+0x59a0) / 0x60;
67
68 if (r < 0x91) return 0x91;
69 if (r > 0xef) return 0xef;
70 return r;
71}
72
73static inline short quantize_db(short db) {
74 return db_to_regval(db) * 0x60 - 0x59a0;
75}
76
77
78static inline int
79register_width(enum tas3001c_reg_t r)
80{
81 switch(r) {
82 case TAS3001C_REG_MCR:
83 case TAS3001C_REG_TREBLE:
84 case TAS3001C_REG_BASS:
85 return 1;
86
87 case TAS3001C_REG_DRC:
88 return 2;
89
90 case TAS3001C_REG_MIXER1:
91 case TAS3001C_REG_MIXER2:
92 return 3;
93
94 case TAS3001C_REG_VOLUME:
95 return 6;
96
97 case TAS3001C_REG_LEFT_BIQUAD0:
98 case TAS3001C_REG_LEFT_BIQUAD1:
99 case TAS3001C_REG_LEFT_BIQUAD2:
100 case TAS3001C_REG_LEFT_BIQUAD3:
101 case TAS3001C_REG_LEFT_BIQUAD4:
102 case TAS3001C_REG_LEFT_BIQUAD5:
103 case TAS3001C_REG_LEFT_BIQUAD6:
104
105 case TAS3001C_REG_RIGHT_BIQUAD0:
106 case TAS3001C_REG_RIGHT_BIQUAD1:
107 case TAS3001C_REG_RIGHT_BIQUAD2:
108 case TAS3001C_REG_RIGHT_BIQUAD3:
109 case TAS3001C_REG_RIGHT_BIQUAD4:
110 case TAS3001C_REG_RIGHT_BIQUAD5:
111 case TAS3001C_REG_RIGHT_BIQUAD6:
112 return 15;
113
114 default:
115 return 0;
116 }
117}
118
119static int
120tas3001c_write_register( struct tas3001c_data_t *self,
121 enum tas3001c_reg_t reg_num,
122 char *data,
123 uint write_mode)
124{
125 if (reg_num==TAS3001C_REG_MCR ||
126 reg_num==TAS3001C_REG_BASS ||
127 reg_num==TAS3001C_REG_TREBLE) {
128 return tas_write_byte_register(&self->super,
129 (uint)reg_num,
130 *data,
131 write_mode);
132 } else {
133 return tas_write_register(&self->super,
134 (uint)reg_num,
135 register_width(reg_num),
136 data,
137 write_mode);
138 }
139}
140
141static int
142tas3001c_sync_register( struct tas3001c_data_t *self,
143 enum tas3001c_reg_t reg_num)
144{
145 if (reg_num==TAS3001C_REG_MCR ||
146 reg_num==TAS3001C_REG_BASS ||
147 reg_num==TAS3001C_REG_TREBLE) {
148 return tas_sync_byte_register(&self->super,
149 (uint)reg_num,
150 register_width(reg_num));
151 } else {
152 return tas_sync_register(&self->super,
153 (uint)reg_num,
154 register_width(reg_num));
155 }
156}
157
158static int
159tas3001c_read_register( struct tas3001c_data_t *self,
160 enum tas3001c_reg_t reg_num,
161 char *data,
162 uint write_mode)
163{
164 return tas_read_register(&self->super,
165 (uint)reg_num,
166 register_width(reg_num),
167 data);
168}
169
170static inline int
171tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
172{
173 if (fast)
174 self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
175 else
176 self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
177 return tas3001c_sync_register(self,TAS3001C_REG_MCR);
178}
179
180static uint
181tas3001c_supported_mixers(struct tas3001c_data_t *self)
182{
183 return SOUND_MASK_VOLUME |
184 SOUND_MASK_PCM |
185 SOUND_MASK_ALTPCM |
186 SOUND_MASK_TREBLE |
187 SOUND_MASK_BASS;
188}
189
190static int
191tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
192{
193 switch(mixer) {
194 case SOUND_MIXER_VOLUME:
195 return 1;
196 default:
197 return 0;
198 }
199}
200
201static uint
202tas3001c_stereo_mixers(struct tas3001c_data_t *self)
203{
204 uint r=tas3001c_supported_mixers(self);
205 uint i;
206
207 for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
208 if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
209 r &= ~(1<<i);
210 return r;
211}
212
213static int
214tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
215{
216 if (!self)
217 return -1;
218
219 *level=self->super.mixer[mixer];
220
221 return 0;
222}
223
224static int
225tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
226{
227 int rc;
228 tas_shadow_t *shadow;
229
230 uint temp;
231 uint offset=0;
232
233 if (!self)
234 return -1;
235
236 shadow=self->super.shadow;
237
238 if (!tas3001c_mixer_is_stereo(self,mixer))
239 level = tas_mono_to_stereo(level);
240
241 switch(mixer) {
242 case SOUND_MIXER_VOLUME:
243 temp = tas3001c_gain.master[level&0xff];
244 shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
245 shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff;
246 shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff;
247 temp = tas3001c_gain.master[(level>>8)&0xff];
248 shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
249 shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff;
250 shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff;
251 rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
252 break;
253 case SOUND_MIXER_ALTPCM:
254 /* tas3001c_fast_load(self, 1); */
255 level = tas_mono_to_stereo(level);
256 temp = tas3001c_gain.mixer[level&0xff];
257 shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
258 shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff;
259 shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff;
260 rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
261 /* tas3001c_fast_load(self, 0); */
262 break;
263 case SOUND_MIXER_PCM:
264 /* tas3001c_fast_load(self, 1); */
265 level = tas_mono_to_stereo(level);
266 temp = tas3001c_gain.mixer[level&0xff];
267 shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
268 shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff;
269 shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff;
270 rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
271 /* tas3001c_fast_load(self, 0); */
272 break;
273 case SOUND_MIXER_TREBLE:
274 temp = tas3001c_gain.treble[level&0xff];
275 shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
276 rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
277 break;
278 case SOUND_MIXER_BASS:
279 temp = tas3001c_gain.bass[level&0xff];
280 shadow[TAS3001C_REG_BASS][0]=temp&0xff;
281 rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
282 break;
283 default:
284 rc = -1;
285 break;
286 }
287 if (rc < 0)
288 return rc;
289 self->super.mixer[mixer]=level;
290 return 0;
291}
292
293static int
294tas3001c_leave_sleep(struct tas3001c_data_t *self)
295{
296 unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
297
298 if (!self)
299 return -1;
300
301 /* Make sure something answers on the i2c bus */
302 if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
303 WRITE_NORMAL|FORCE_WRITE) < 0)
304 return -1;
305
306 tas3001c_fast_load(self, 1);
307
308 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
309 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
310 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
311 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
312 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
313 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
314
315 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
316 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
317 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
318 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
319 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
320 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
321
322 tas3001c_fast_load(self, 0);
323
324 (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
325 (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
326 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
327 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
328 (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
329
330 return 0;
331}
332
333static int
334tas3001c_enter_sleep(struct tas3001c_data_t *self)
335{
336 /* Stub for now, but I have the details on low-power mode */
337 if (!self)
338 return -1;
339 return 0;
340}
341
342static int
343tas3001c_sync_biquad( struct tas3001c_data_t *self,
344 u_int channel,
345 u_int filter)
346{
347 enum tas3001c_reg_t reg;
348
349 if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
350 filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
351
352 reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
353
354 return tas3001c_sync_register(self,reg);
355}
356
357static int
358tas3001c_write_biquad_shadow( struct tas3001c_data_t *self,
359 u_int channel,
360 u_int filter,
361 const union tas_biquad_t *biquad)
362{
363 tas_shadow_t *shadow=self->super.shadow;
364 enum tas3001c_reg_t reg;
365
366 if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
367 filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
368
369 reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
370
371 SET_4_20(shadow[reg], 0,biquad->coeff.b0);
372 SET_4_20(shadow[reg], 3,biquad->coeff.b1);
373 SET_4_20(shadow[reg], 6,biquad->coeff.b2);
374 SET_4_20(shadow[reg], 9,biquad->coeff.a1);
375 SET_4_20(shadow[reg],12,biquad->coeff.a2);
376
377 return 0;
378}
379
380static int
381tas3001c_write_biquad( struct tas3001c_data_t *self,
382 u_int channel,
383 u_int filter,
384 const union tas_biquad_t *biquad)
385{
386 int rc;
387
388 rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
389 if (rc < 0) return rc;
390
391 return tas3001c_sync_biquad(self, channel, filter);
392}
393
394static int
395tas3001c_write_biquad_list( struct tas3001c_data_t *self,
396 u_int filter_count,
397 u_int flags,
398 struct tas_biquad_ctrl_t *biquads)
399{
400 int i;
401 int rc;
402
403 if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
404
405 for (i=0; i<filter_count; i++) {
406 rc=tas3001c_write_biquad(self,
407 biquads[i].channel,
408 biquads[i].filter,
409 &biquads[i].data);
410 if (rc < 0) break;
411 }
412
413 if (flags & TAS_BIQUAD_FAST_LOAD) {
414 tas3001c_fast_load(self,0);
415
416 (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
417 (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
418 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
419 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
420 (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
421 }
422
423 return rc;
424}
425
426static int
427tas3001c_read_biquad( struct tas3001c_data_t *self,
428 u_int channel,
429 u_int filter,
430 union tas_biquad_t *biquad)
431{
432 tas_shadow_t *shadow=self->super.shadow;
433 enum tas3001c_reg_t reg;
434
435 if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
436 filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
437
438 reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
439
440 biquad->coeff.b0=GET_4_20(shadow[reg], 0);
441 biquad->coeff.b1=GET_4_20(shadow[reg], 3);
442 biquad->coeff.b2=GET_4_20(shadow[reg], 6);
443 biquad->coeff.a1=GET_4_20(shadow[reg], 9);
444 biquad->coeff.a2=GET_4_20(shadow[reg],12);
445
446 return 0;
447}
448
449static int
450tas3001c_eq_rw( struct tas3001c_data_t *self,
451 u_int cmd,
452 u_long arg)
453{
454 int rc;
455 struct tas_biquad_ctrl_t biquad;
456 void __user *argp = (void __user *)arg;
457
458 if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
459 return -EFAULT;
460 }
461
462 if (cmd & SIOC_IN) {
463 rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
464 if (rc != 0) return rc;
465 }
466
467 if (cmd & SIOC_OUT) {
468 rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
469 if (rc != 0) return rc;
470
471 if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
472 return -EFAULT;
473 }
474
475 }
476 return 0;
477}
478
479static int
480tas3001c_eq_list_rw( struct tas3001c_data_t *self,
481 u_int cmd,
482 u_long arg)
483{
484 int rc;
485 int filter_count;
486 int flags;
487 int i,j;
488 char sync_required[2][6];
489 struct tas_biquad_ctrl_t biquad;
490 struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
491
492 memset(sync_required,0,sizeof(sync_required));
493
494 if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
495 return -EFAULT;
496
497 if (copy_from_user(&flags, &argp->flags, sizeof(int)))
498 return -EFAULT;
499
500 if (cmd & SIOC_IN) {
501 }
502
503 for (i=0; i < filter_count; i++) {
504 if (copy_from_user(&biquad, &argp->biquads[i],
505 sizeof(struct tas_biquad_ctrl_t))) {
506 return -EFAULT;
507 }
508
509 if (cmd & SIOC_IN) {
510 sync_required[biquad.channel][biquad.filter]=1;
511 rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
512 if (rc != 0) return rc;
513 }
514
515 if (cmd & SIOC_OUT) {
516 rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
517 if (rc != 0) return rc;
518
519 if (copy_to_user(&argp->biquads[i], &biquad,
520 sizeof(struct tas_biquad_ctrl_t))) {
521 return -EFAULT;
522 }
523 }
524 }
525
526 if (cmd & SIOC_IN) {
527 if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
528 for (i=0; i<2; i++) {
529 for (j=0; j<6; j++) {
530 if (sync_required[i][j]) {
531 rc=tas3001c_sync_biquad(self, i, j);
532 if (rc < 0) return rc;
533 }
534 }
535 }
536 if (flags & TAS_BIQUAD_FAST_LOAD) {
537 tas3001c_fast_load(self,0);
538 /* now we need to set up the mixers again,
539 because leaving fast mode resets them. */
540 (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
541 (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
542 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
543 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
544 (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
545 }
546 }
547
548 return 0;
549}
550
551static int
552tas3001c_update_drce( struct tas3001c_data_t *self,
553 int flags,
554 struct tas_drce_t *drce)
555{
556 tas_shadow_t *shadow;
557 shadow=self->super.shadow;
558
559 shadow[TAS3001C_REG_DRC][1] = 0xc1;
560
561 if (flags & TAS_DRCE_THRESHOLD) {
562 self->drce_state.threshold=quantize_db(drce->threshold);
563 shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
564 }
565
566 if (flags & TAS_DRCE_ENABLE) {
567 self->drce_state.enable = drce->enable;
568 }
569
570 if (!self->drce_state.enable) {
571 shadow[TAS3001C_REG_DRC][0] = 0xf0;
572 }
573
574#ifdef DEBUG_DRCE
575 printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
576 self->drce_state.enable,
577 self->drce_state.threshold);
578
579 printk("DRCE IOCTL: reg [ %02x %02x ]\n",
580 (unsigned char)shadow[TAS3001C_REG_DRC][0],
581 (unsigned char)shadow[TAS3001C_REG_DRC][1]);
582#endif
583
584 return tas3001c_sync_register(self, TAS3001C_REG_DRC);
585}
586
587static int
588tas3001c_drce_rw( struct tas3001c_data_t *self,
589 u_int cmd,
590 u_long arg)
591{
592 int rc;
593 struct tas_drce_ctrl_t drce_ctrl;
594 void __user *argp = (void __user *)arg;
595
596 if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
597 return -EFAULT;
598
599#ifdef DEBUG_DRCE
600 printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
601 drce_ctrl.flags,
602 drce_ctrl.data.enable,
603 drce_ctrl.data.threshold);
604#endif
605
606 if (cmd & SIOC_IN) {
607 rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
608 if (rc < 0)
609 return rc;
610 }
611
612 if (cmd & SIOC_OUT) {
613 if (drce_ctrl.flags & TAS_DRCE_ENABLE)
614 drce_ctrl.data.enable = self->drce_state.enable;
615
616 if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
617 drce_ctrl.data.threshold = self->drce_state.threshold;
618
619 if (copy_to_user(argp, &drce_ctrl,
620 sizeof(struct tas_drce_ctrl_t))) {
621 return -EFAULT;
622 }
623 }
624
625 return 0;
626}
627
628static void
629tas3001c_update_device_parameters(struct tas3001c_data_t *self)
630{
631 int i,j;
632
633 if (!self) return;
634
635 if (self->output_id == TAS_OUTPUT_HEADPHONES) {
636 tas3001c_fast_load(self, 1);
637
638 for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
639 for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
640 tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
641 }
642 }
643
644 tas3001c_fast_load(self, 0);
645
646 (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
647 (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
648 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
649 (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
650 (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
651
652 return;
653 }
654
655 for (i=0; tas3001c_eq_prefs[i]; i++) {
656 struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
657
658 if (eq->device_id == self->device_id &&
659 (eq->output_id == 0 || eq->output_id == self->output_id) &&
660 (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
661
662 tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
663 tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
664
665 break;
666 }
667 }
668}
669
670static void
671tas3001c_device_change_handler(struct work_struct *work)
672{
673 struct tas3001c_data_t *self;
674 self = container_of(work, struct tas3001c_data_t, change);
675 tas3001c_update_device_parameters(self);
676}
677
678static int
679tas3001c_output_device_change( struct tas3001c_data_t *self,
680 int device_id,
681 int output_id,
682 int speaker_id)
683{
684 self->device_id=device_id;
685 self->output_id=output_id;
686 self->speaker_id=speaker_id;
687
688 schedule_work(&self->change);
689 return 0;
690}
691
692static int
693tas3001c_device_ioctl( struct tas3001c_data_t *self,
694 u_int cmd,
695 u_long arg)
696{
697 uint __user *argp = (void __user *)arg;
698 switch (cmd) {
699 case TAS_READ_EQ:
700 case TAS_WRITE_EQ:
701 return tas3001c_eq_rw(self, cmd, arg);
702
703 case TAS_READ_EQ_LIST:
704 case TAS_WRITE_EQ_LIST:
705 return tas3001c_eq_list_rw(self, cmd, arg);
706
707 case TAS_READ_EQ_FILTER_COUNT:
708 put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp);
709 return 0;
710
711 case TAS_READ_EQ_CHANNEL_COUNT:
712 put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp);
713 return 0;
714
715 case TAS_READ_DRCE:
716 case TAS_WRITE_DRCE:
717 return tas3001c_drce_rw(self, cmd, arg);
718
719 case TAS_READ_DRCE_CAPS:
720 put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp);
721 return 0;
722
723 case TAS_READ_DRCE_MIN:
724 case TAS_READ_DRCE_MAX: {
725 struct tas_drce_ctrl_t drce_ctrl;
726
727 if (copy_from_user(&drce_ctrl, argp,
728 sizeof(struct tas_drce_ctrl_t))) {
729 return -EFAULT;
730 }
731
732 if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
733 if (cmd == TAS_READ_DRCE_MIN) {
734 drce_ctrl.data.threshold=-36<<8;
735 } else {
736 drce_ctrl.data.threshold=-6<<8;
737 }
738 }
739
740 if (copy_to_user(argp, &drce_ctrl,
741 sizeof(struct tas_drce_ctrl_t))) {
742 return -EFAULT;
743 }
744 }
745 }
746
747 return -EINVAL;
748}
749
750static int
751tas3001c_init_mixer(struct tas3001c_data_t *self)
752{
753 unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
754
755 /* Make sure something answers on the i2c bus */
756 if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
757 WRITE_NORMAL|FORCE_WRITE) < 0)
758 return -1;
759
760 tas3001c_fast_load(self, 1);
761
762 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
763 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
764 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
765 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
766 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
767 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
768 (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
769
770 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
771 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
772 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
773 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
774 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
775 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
776 (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
777
778 tas3001c_fast_load(self, 0);
779
780 tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
781 tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
782 tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
783
784 tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
785 tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
786
787 return 0;
788}
789
790static int
791tas3001c_uninit_mixer(struct tas3001c_data_t *self)
792{
793 tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
794 tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0);
795 tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
796
797 tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0);
798 tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
799
800 return 0;
801}
802
803static int
804tas3001c_init(struct i2c_client *client)
805{
806 struct tas3001c_data_t *self;
807 size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
808 int i, j;
809
810 self = kzalloc(sz, GFP_KERNEL);
811 if (!self)
812 return -ENOMEM;
813
814 self->super.client = client;
815 self->super.shadow = (tas_shadow_t *)(self+1);
816 self->output_id = TAS_OUTPUT_HEADPHONES;
817
818 dev_set_drvdata(&client->dev, self);
819
820 for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
821 for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
822 tas3001c_write_biquad_shadow(self, i, j,
823 &tas3001c_eq_unity);
824
825 INIT_WORK(&self->change, tas3001c_device_change_handler);
826 return 0;
827}
828
829static void
830tas3001c_uninit(struct tas3001c_data_t *self)
831{
832 tas3001c_uninit_mixer(self);
833 kfree(self);
834}
835
836struct tas_driver_hooks_t tas3001c_hooks = {
837 .init = (tas_hook_init_t)tas3001c_init,
838 .post_init = (tas_hook_post_init_t)tas3001c_init_mixer,
839 .uninit = (tas_hook_uninit_t)tas3001c_uninit,
840 .get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
841 .set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
842 .enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
843 .leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
844 .supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
845 .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
846 .stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
847 .output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change,
848 .device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
849};
diff --git a/sound/oss/dmasound/tas3001c.h b/sound/oss/dmasound/tas3001c.h
deleted file mode 100644
index 3660da33a2db..000000000000
--- a/sound/oss/dmasound/tas3001c.h
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Header file for the i2c/i2s based TA3001c sound chip used
3 * on some Apple hardware. Also known as "tumbler".
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file COPYING in the main directory of this archive
7 * for more details.
8 *
9 * Written by Christopher C. Chimelis <chris@debian.org>
10 */
11
12#ifndef _TAS3001C_H_
13#define _TAS3001C_H_
14
15#include <linux/types.h>
16
17#include "tas_common.h"
18#include "tas_eq_prefs.h"
19
20/*
21 * Macros that correspond to the registers that we write to
22 * when setting the various values.
23 */
24
25#define TAS3001C_VERSION "0.3"
26#define TAS3001C_DATE "20011214"
27
28#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
29#define I2C_DRIVERID_TAS3001C (I2C_DRIVERID_TAS_BASE+0)
30
31extern struct tas_driver_hooks_t tas3001c_hooks;
32extern struct tas_gain_t tas3001c_gain;
33extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
34
35enum tas3001c_reg_t {
36 TAS3001C_REG_MCR = 0x01,
37 TAS3001C_REG_DRC = 0x02,
38
39 TAS3001C_REG_VOLUME = 0x04,
40 TAS3001C_REG_TREBLE = 0x05,
41 TAS3001C_REG_BASS = 0x06,
42 TAS3001C_REG_MIXER1 = 0x07,
43 TAS3001C_REG_MIXER2 = 0x08,
44
45 TAS3001C_REG_LEFT_BIQUAD0 = 0x0a,
46 TAS3001C_REG_LEFT_BIQUAD1 = 0x0b,
47 TAS3001C_REG_LEFT_BIQUAD2 = 0x0c,
48 TAS3001C_REG_LEFT_BIQUAD3 = 0x0d,
49 TAS3001C_REG_LEFT_BIQUAD4 = 0x0e,
50 TAS3001C_REG_LEFT_BIQUAD5 = 0x0f,
51 TAS3001C_REG_LEFT_BIQUAD6 = 0x10,
52
53 TAS3001C_REG_RIGHT_BIQUAD0 = 0x13,
54 TAS3001C_REG_RIGHT_BIQUAD1 = 0x14,
55 TAS3001C_REG_RIGHT_BIQUAD2 = 0x15,
56 TAS3001C_REG_RIGHT_BIQUAD3 = 0x16,
57 TAS3001C_REG_RIGHT_BIQUAD4 = 0x17,
58 TAS3001C_REG_RIGHT_BIQUAD5 = 0x18,
59 TAS3001C_REG_RIGHT_BIQUAD6 = 0x19,
60
61 TAS3001C_REG_MAX = 0x20
62};
63
64#endif /* _TAS3001C_H_ */
diff --git a/sound/oss/dmasound/tas3001c_tables.c b/sound/oss/dmasound/tas3001c_tables.c
deleted file mode 100644
index 1768fa95f25b..000000000000
--- a/sound/oss/dmasound/tas3001c_tables.c
+++ /dev/null
@@ -1,375 +0,0 @@
1#include "tas_common.h"
2#include "tas_eq_prefs.h"
3
4static struct tas_drce_t eqp_0e_2_1_drce = {
5 .enable = 1,
6 .above = { .val = 3.0 * (1<<8), .expand = 0 },
7 .below = { .val = 1.0 * (1<<8), .expand = 0 },
8 .threshold = -15.33 * (1<<8),
9 .energy = 2.4 * (1<<12),
10 .attack = 0.013 * (1<<12),
11 .decay = 0.212 * (1<<12),
12};
13
14static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
15 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
16 { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
17 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
18 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
19 { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
20 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
21
22 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
23 { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
24 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
25 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
26 { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
27 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
28};
29
30static struct tas_eq_pref_t eqp_0e_2_1 = {
31 .sample_rate = 44100,
32 .device_id = 0x0e,
33 .output_id = TAS_OUTPUT_EXTERNAL_SPKR,
34 .speaker_id = 0x01,
35
36 .drce = &eqp_0e_2_1_drce,
37
38 .filter_count = 12,
39 .biquads = eqp_0e_2_1_biquads
40};
41
42/* ======================================================================== */
43
44static struct tas_drce_t eqp_10_1_0_drce={
45 .enable = 1,
46 .above = { .val = 3.0 * (1<<8), .expand = 0 },
47 .below = { .val = 1.0 * (1<<8), .expand = 0 },
48 .threshold = -12.46 * (1<<8),
49 .energy = 2.4 * (1<<12),
50 .attack = 0.013 * (1<<12),
51 .decay = 0.212 * (1<<12),
52};
53
54static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
55 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
56 { .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
57 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
58 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
59 { .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
60 { .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
61
62 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
63 { .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
64 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
65 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
66 { .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
67 { .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
68};
69
70static struct tas_eq_pref_t eqp_10_1_0 = {
71 .sample_rate = 44100,
72 .device_id = 0x10,
73 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
74 .speaker_id = 0x00,
75
76 .drce = &eqp_10_1_0_drce,
77
78 .filter_count = 12,
79 .biquads = eqp_10_1_0_biquads
80};
81
82/* ======================================================================== */
83
84static struct tas_drce_t eqp_15_2_1_drce={
85 .enable = 1,
86 .above = { .val = 3.0 * (1<<8), .expand = 0 },
87 .below = { .val = 1.0 * (1<<8), .expand = 0 },
88 .threshold = -15.33 * (1<<8),
89 .energy = 2.4 * (1<<12),
90 .attack = 0.013 * (1<<12),
91 .decay = 0.212 * (1<<12),
92};
93
94static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
95 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
96 { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
97 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
98 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
99 { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
100 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
101
102 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
103 { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
104 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
105 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
106 { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
107 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
108};
109
110static struct tas_eq_pref_t eqp_15_2_1 = {
111 .sample_rate = 44100,
112 .device_id = 0x15,
113 .output_id = TAS_OUTPUT_EXTERNAL_SPKR,
114 .speaker_id = 0x01,
115
116 .drce = &eqp_15_2_1_drce,
117
118 .filter_count = 12,
119 .biquads = eqp_15_2_1_biquads
120};
121
122/* ======================================================================== */
123
124static struct tas_drce_t eqp_15_1_0_drce={
125 .enable = 1,
126 .above = { .val = 3.0 * (1<<8), .expand = 0 },
127 .below = { .val = 1.0 * (1<<8), .expand = 0 },
128 .threshold = 0.0 * (1<<8),
129 .energy = 2.4 * (1<<12),
130 .attack = 0.013 * (1<<12),
131 .decay = 0.212 * (1<<12),
132};
133
134static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
135 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
136 { .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
137 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
138 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
139 { .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
140 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
141
142 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
143 { .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
144 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
145 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
146 { .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
147 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
148};
149
150static struct tas_eq_pref_t eqp_15_1_0 = {
151 .sample_rate = 44100,
152 .device_id = 0x15,
153 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
154 .speaker_id = 0x00,
155
156 .drce = &eqp_15_1_0_drce,
157
158 .filter_count = 12,
159 .biquads = eqp_15_1_0_biquads
160};
161
162/* ======================================================================== */
163
164static struct tas_drce_t eqp_0f_2_1_drce={
165 .enable = 1,
166 .above = { .val = 3.0 * (1<<8), .expand = 0 },
167 .below = { .val = 1.0 * (1<<8), .expand = 0 },
168 .threshold = -15.33 * (1<<8),
169 .energy = 2.4 * (1<<12),
170 .attack = 0.013 * (1<<12),
171 .decay = 0.212 * (1<<12),
172};
173
174static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
175 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
176 { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
177 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
178 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
179 { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
180 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
181
182 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
183 { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
184 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
185 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
186 { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
187 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
188};
189
190static struct tas_eq_pref_t eqp_0f_2_1 = {
191 .sample_rate = 44100,
192 .device_id = 0x0f,
193 .output_id = TAS_OUTPUT_EXTERNAL_SPKR,
194 .speaker_id = 0x01,
195
196 .drce = &eqp_0f_2_1_drce,
197
198 .filter_count = 12,
199 .biquads = eqp_0f_2_1_biquads
200};
201
202/* ======================================================================== */
203
204static struct tas_drce_t eqp_0f_1_0_drce={
205 .enable = 1,
206 .above = { .val = 3.0 * (1<<8), .expand = 0 },
207 .below = { .val = 1.0 * (1<<8), .expand = 0 },
208 .threshold = -15.33 * (1<<8),
209 .energy = 2.4 * (1<<12),
210 .attack = 0.013 * (1<<12),
211 .decay = 0.212 * (1<<12),
212};
213
214static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
215 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
216 { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
217 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
218 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
219 { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
220 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
221
222 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
223 { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
224 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
225 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
226 { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
227 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
228};
229
230static struct tas_eq_pref_t eqp_0f_1_0 = {
231 .sample_rate = 44100,
232 .device_id = 0x0f,
233 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
234 .speaker_id = 0x00,
235
236 .drce = &eqp_0f_1_0_drce,
237
238 .filter_count = 12,
239 .biquads = eqp_0f_1_0_biquads
240};
241
242/* ======================================================================== */
243
244static uint tas3001c_master_tab[]={
245 0x0, 0x75, 0x9c, 0xbb,
246 0xdb, 0xfb, 0x11e, 0x143,
247 0x16b, 0x196, 0x1c3, 0x1f5,
248 0x229, 0x263, 0x29f, 0x2e1,
249 0x328, 0x373, 0x3c5, 0x41b,
250 0x478, 0x4dc, 0x547, 0x5b8,
251 0x633, 0x6b5, 0x740, 0x7d5,
252 0x873, 0x91c, 0x9d2, 0xa92,
253 0xb5e, 0xc39, 0xd22, 0xe19,
254 0xf20, 0x1037, 0x1161, 0x129e,
255 0x13ed, 0x1551, 0x16ca, 0x185d,
256 0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
257 0x21c1, 0x23fa, 0x2655, 0x28d6,
258 0x2b7c, 0x2e4a, 0x3141, 0x3464,
259 0x37b4, 0x3b35, 0x3ee9, 0x42d3,
260 0x46f6, 0x4b53, 0x4ff0, 0x54ce,
261 0x59f2, 0x5f5f, 0x6519, 0x6b24,
262 0x7183, 0x783c, 0x7f53, 0x86cc,
263 0x8ead, 0x96fa, 0x9fba, 0xa8f2,
264 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
265 0xdee8, 0xeb75, 0xf8aa, 0x1068e,
266 0x1152a, 0x12487, 0x134ad, 0x145a5,
267 0x1577b, 0x16a37, 0x17df5, 0x192bd,
268 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
269 0x20b55, 0x22727, 0x24456, 0x262f2,
270 0x2830b
271};
272
273static uint tas3001c_mixer_tab[]={
274 0x0, 0x748, 0x9be, 0xbaf,
275 0xda4, 0xfb1, 0x11de, 0x1431,
276 0x16ad, 0x1959, 0x1c37, 0x1f4b,
277 0x2298, 0x2628, 0x29fb, 0x2e12,
278 0x327d, 0x3734, 0x3c47, 0x41b4,
279 0x4787, 0x4dbe, 0x546d, 0x5b86,
280 0x632e, 0x6b52, 0x7400, 0x7d54,
281 0x873b, 0x91c6, 0x9d1a, 0xa920,
282 0xb5e5, 0xc38c, 0xd21b, 0xe18f,
283 0xf1f5, 0x1036a, 0x1160f, 0x129d6,
284 0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
285 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
286 0x21c0f, 0x23fa3, 0x26552, 0x28d64,
287 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
288 0x37b44, 0x3b353, 0x3ee94, 0x42d30,
289 0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
290 0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
291 0x71835, 0x783c3, 0x7f52c, 0x86cc0,
292 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
293 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
294 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
295 0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
296 0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
297 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
298 0x20b542, 0x227268, 0x244564, 0x262f26,
299 0x2830af
300};
301
302static uint tas3001c_treble_tab[]={
303 0x96, 0x95, 0x95, 0x94,
304 0x93, 0x92, 0x92, 0x91,
305 0x90, 0x90, 0x8f, 0x8e,
306 0x8d, 0x8d, 0x8c, 0x8b,
307 0x8a, 0x8a, 0x89, 0x88,
308 0x88, 0x87, 0x86, 0x85,
309 0x85, 0x84, 0x83, 0x83,
310 0x82, 0x81, 0x80, 0x80,
311 0x7f, 0x7e, 0x7e, 0x7d,
312 0x7c, 0x7b, 0x7b, 0x7a,
313 0x79, 0x78, 0x78, 0x77,
314 0x76, 0x76, 0x75, 0x74,
315 0x73, 0x73, 0x72, 0x71,
316 0x71, 0x70, 0x6e, 0x6d,
317 0x6d, 0x6c, 0x6b, 0x6a,
318 0x69, 0x68, 0x67, 0x66,
319 0x65, 0x63, 0x62, 0x62,
320 0x60, 0x5f, 0x5d, 0x5c,
321 0x5a, 0x58, 0x56, 0x55,
322 0x53, 0x51, 0x4f, 0x4c,
323 0x4a, 0x48, 0x45, 0x43,
324 0x40, 0x3d, 0x3a, 0x37,
325 0x35, 0x32, 0x2e, 0x2a,
326 0x27, 0x22, 0x1e, 0x1a,
327 0x15, 0x11, 0xc, 0x7,
328 0x1
329};
330
331static uint tas3001c_bass_tab[]={
332 0x86, 0x83, 0x81, 0x7f,
333 0x7d, 0x7b, 0x79, 0x78,
334 0x76, 0x75, 0x74, 0x72,
335 0x71, 0x6f, 0x6e, 0x6d,
336 0x6c, 0x6b, 0x69, 0x67,
337 0x65, 0x64, 0x61, 0x60,
338 0x5e, 0x5d, 0x5c, 0x5b,
339 0x5a, 0x59, 0x58, 0x57,
340 0x56, 0x55, 0x55, 0x54,
341 0x53, 0x52, 0x50, 0x4f,
342 0x4d, 0x4c, 0x4b, 0x49,
343 0x47, 0x45, 0x44, 0x42,
344 0x41, 0x3f, 0x3e, 0x3d,
345 0x3c, 0x3b, 0x39, 0x38,
346 0x37, 0x36, 0x35, 0x34,
347 0x33, 0x31, 0x30, 0x2f,
348 0x2e, 0x2c, 0x2b, 0x2b,
349 0x29, 0x28, 0x27, 0x26,
350 0x25, 0x24, 0x22, 0x21,
351 0x20, 0x1e, 0x1c, 0x19,
352 0x18, 0x18, 0x17, 0x16,
353 0x15, 0x14, 0x13, 0x12,
354 0x11, 0x10, 0xf, 0xe,
355 0xd, 0xb, 0xa, 0x9,
356 0x8, 0x6, 0x4, 0x2,
357 0x1
358};
359
360struct tas_gain_t tas3001c_gain = {
361 .master = tas3001c_master_tab,
362 .treble = tas3001c_treble_tab,
363 .bass = tas3001c_bass_tab,
364 .mixer = tas3001c_mixer_tab
365};
366
367struct tas_eq_pref_t *tas3001c_eq_prefs[]={
368 &eqp_0e_2_1,
369 &eqp_10_1_0,
370 &eqp_15_2_1,
371 &eqp_15_1_0,
372 &eqp_0f_2_1,
373 &eqp_0f_1_0,
374 NULL
375};
diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c
deleted file mode 100644
index 678bf0ff6da2..000000000000
--- a/sound/oss/dmasound/tas3004.c
+++ /dev/null
@@ -1,1138 +0,0 @@
1/*
2 * Driver for the i2c/i2s based TA3004 sound chip used
3 * on some Apple hardware. Also known as "snapper".
4 *
5 * Tobias Sargeant <tobias.sargeant@bigpond.com>
6 * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
7 *
8 * Input support by Renzo Davoli <renzo@cs.unibo.it>
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/proc_fs.h>
15#include <linux/ioport.h>
16#include <linux/sysctl.h>
17#include <linux/types.h>
18#include <linux/i2c.h>
19#include <linux/init.h>
20#include <linux/soundcard.h>
21#include <linux/interrupt.h>
22#include <linux/workqueue.h>
23
24#include <asm/uaccess.h>
25#include <asm/errno.h>
26#include <asm/io.h>
27#include <asm/prom.h>
28
29#include "dmasound.h"
30#include "tas_common.h"
31#include "tas3004.h"
32
33#include "tas_ioctl.h"
34
35/* #define DEBUG_DRCE */
36
37#define TAS3004_BIQUAD_FILTER_COUNT 7
38#define TAS3004_BIQUAD_CHANNEL_COUNT 2
39
40#define VOL_DEFAULT (100 * 4 / 5)
41#define INPUT_DEFAULT (100 * 4 / 5)
42#define BASS_DEFAULT (100 / 2)
43#define TREBLE_DEFAULT (100 / 2)
44
45struct tas3004_data_t {
46 struct tas_data_t super;
47 int device_id;
48 int output_id;
49 int speaker_id;
50 struct tas_drce_t drce_state;
51 struct work_struct change;
52};
53
54#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
55
56#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
57
58
59static const union tas_biquad_t tas3004_eq_unity = {
60 .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
61};
62
63
64static const struct tas_drce_t tas3004_drce_min = {
65 .enable = 1,
66 .above = { .val = MAKE_RATIO(16,0), .expand = 0 },
67 .below = { .val = MAKE_RATIO(2,0), .expand = 0 },
68 .threshold = -0x59a0,
69 .energy = MAKE_TIME(0, 1700),
70 .attack = MAKE_TIME(0, 1700),
71 .decay = MAKE_TIME(0, 1700),
72};
73
74
75static const struct tas_drce_t tas3004_drce_max = {
76 .enable = 1,
77 .above = { .val = MAKE_RATIO(1,500), .expand = 1 },
78 .below = { .val = MAKE_RATIO(2,0), .expand = 1 },
79 .threshold = -0x0,
80 .energy = MAKE_TIME(2,400000),
81 .attack = MAKE_TIME(2,400000),
82 .decay = MAKE_TIME(2,400000),
83};
84
85
86static const unsigned short time_constants[]={
87 MAKE_TIME(0, 1700),
88 MAKE_TIME(0, 3500),
89 MAKE_TIME(0, 6700),
90 MAKE_TIME(0, 13000),
91 MAKE_TIME(0, 26000),
92 MAKE_TIME(0, 53000),
93 MAKE_TIME(0,106000),
94 MAKE_TIME(0,212000),
95 MAKE_TIME(0,425000),
96 MAKE_TIME(0,850000),
97 MAKE_TIME(1,700000),
98 MAKE_TIME(2,400000),
99};
100
101static const unsigned short above_threshold_compression_ratio[]={
102 MAKE_RATIO( 1, 70),
103 MAKE_RATIO( 1,140),
104 MAKE_RATIO( 1,230),
105 MAKE_RATIO( 1,330),
106 MAKE_RATIO( 1,450),
107 MAKE_RATIO( 1,600),
108 MAKE_RATIO( 1,780),
109 MAKE_RATIO( 2, 0),
110 MAKE_RATIO( 2,290),
111 MAKE_RATIO( 2,670),
112 MAKE_RATIO( 3,200),
113 MAKE_RATIO( 4, 0),
114 MAKE_RATIO( 5,330),
115 MAKE_RATIO( 8, 0),
116 MAKE_RATIO(16, 0),
117};
118
119static const unsigned short above_threshold_expansion_ratio[]={
120 MAKE_RATIO(1, 60),
121 MAKE_RATIO(1,130),
122 MAKE_RATIO(1,190),
123 MAKE_RATIO(1,250),
124 MAKE_RATIO(1,310),
125 MAKE_RATIO(1,380),
126 MAKE_RATIO(1,440),
127 MAKE_RATIO(1,500)
128};
129
130static const unsigned short below_threshold_compression_ratio[]={
131 MAKE_RATIO(1, 70),
132 MAKE_RATIO(1,140),
133 MAKE_RATIO(1,230),
134 MAKE_RATIO(1,330),
135 MAKE_RATIO(1,450),
136 MAKE_RATIO(1,600),
137 MAKE_RATIO(1,780),
138 MAKE_RATIO(2, 0)
139};
140
141static const unsigned short below_threshold_expansion_ratio[]={
142 MAKE_RATIO(1, 60),
143 MAKE_RATIO(1,130),
144 MAKE_RATIO(1,190),
145 MAKE_RATIO(1,250),
146 MAKE_RATIO(1,310),
147 MAKE_RATIO(1,380),
148 MAKE_RATIO(1,440),
149 MAKE_RATIO(1,500),
150 MAKE_RATIO(1,560),
151 MAKE_RATIO(1,630),
152 MAKE_RATIO(1,690),
153 MAKE_RATIO(1,750),
154 MAKE_RATIO(1,810),
155 MAKE_RATIO(1,880),
156 MAKE_RATIO(1,940),
157 MAKE_RATIO(2, 0)
158};
159
160static inline int
161search( unsigned short val,
162 const unsigned short *arr,
163 const int arrsize) {
164 /*
165 * This could be a binary search, but for small tables,
166 * a linear search is likely to be faster
167 */
168
169 int i;
170
171 for (i=0; i < arrsize; i++)
172 if (arr[i] >= val)
173 goto _1;
174 return arrsize-1;
175 _1:
176 if (i == 0)
177 return 0;
178 return (arr[i]-val < val-arr[i-1]) ? i : i-1;
179}
180
181#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
182
183static inline int
184time_index(unsigned short time)
185{
186 return SEARCH(time, time_constants);
187}
188
189
190static inline int
191above_threshold_compression_index(unsigned short ratio)
192{
193 return SEARCH(ratio, above_threshold_compression_ratio);
194}
195
196
197static inline int
198above_threshold_expansion_index(unsigned short ratio)
199{
200 return SEARCH(ratio, above_threshold_expansion_ratio);
201}
202
203
204static inline int
205below_threshold_compression_index(unsigned short ratio)
206{
207 return SEARCH(ratio, below_threshold_compression_ratio);
208}
209
210
211static inline int
212below_threshold_expansion_index(unsigned short ratio)
213{
214 return SEARCH(ratio, below_threshold_expansion_ratio);
215}
216
217static inline unsigned char db_to_regval(short db) {
218 int r=0;
219
220 r=(db+0x59a0) / 0x60;
221
222 if (r < 0x91) return 0x91;
223 if (r > 0xef) return 0xef;
224 return r;
225}
226
227static inline short quantize_db(short db)
228{
229 return db_to_regval(db) * 0x60 - 0x59a0;
230}
231
232static inline int
233register_width(enum tas3004_reg_t r)
234{
235 switch(r) {
236 case TAS3004_REG_MCR:
237 case TAS3004_REG_TREBLE:
238 case TAS3004_REG_BASS:
239 case TAS3004_REG_ANALOG_CTRL:
240 case TAS3004_REG_TEST1:
241 case TAS3004_REG_TEST2:
242 case TAS3004_REG_MCR2:
243 return 1;
244
245 case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
246 case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
247 return 3;
248
249 case TAS3004_REG_DRC:
250 case TAS3004_REG_VOLUME:
251 return 6;
252
253 case TAS3004_REG_LEFT_MIXER:
254 case TAS3004_REG_RIGHT_MIXER:
255 return 9;
256
257 case TAS3004_REG_TEST:
258 return 10;
259
260 case TAS3004_REG_LEFT_BIQUAD0:
261 case TAS3004_REG_LEFT_BIQUAD1:
262 case TAS3004_REG_LEFT_BIQUAD2:
263 case TAS3004_REG_LEFT_BIQUAD3:
264 case TAS3004_REG_LEFT_BIQUAD4:
265 case TAS3004_REG_LEFT_BIQUAD5:
266 case TAS3004_REG_LEFT_BIQUAD6:
267
268 case TAS3004_REG_RIGHT_BIQUAD0:
269 case TAS3004_REG_RIGHT_BIQUAD1:
270 case TAS3004_REG_RIGHT_BIQUAD2:
271 case TAS3004_REG_RIGHT_BIQUAD3:
272 case TAS3004_REG_RIGHT_BIQUAD4:
273 case TAS3004_REG_RIGHT_BIQUAD5:
274 case TAS3004_REG_RIGHT_BIQUAD6:
275
276 case TAS3004_REG_LEFT_LOUD_BIQUAD:
277 case TAS3004_REG_RIGHT_LOUD_BIQUAD:
278 return 15;
279
280 default:
281 return 0;
282 }
283}
284
285static int
286tas3004_write_register( struct tas3004_data_t *self,
287 enum tas3004_reg_t reg_num,
288 char *data,
289 uint write_mode)
290{
291 if (reg_num==TAS3004_REG_MCR ||
292 reg_num==TAS3004_REG_BASS ||
293 reg_num==TAS3004_REG_TREBLE ||
294 reg_num==TAS3004_REG_ANALOG_CTRL) {
295 return tas_write_byte_register(&self->super,
296 (uint)reg_num,
297 *data,
298 write_mode);
299 } else {
300 return tas_write_register(&self->super,
301 (uint)reg_num,
302 register_width(reg_num),
303 data,
304 write_mode);
305 }
306}
307
308static int
309tas3004_sync_register( struct tas3004_data_t *self,
310 enum tas3004_reg_t reg_num)
311{
312 if (reg_num==TAS3004_REG_MCR ||
313 reg_num==TAS3004_REG_BASS ||
314 reg_num==TAS3004_REG_TREBLE ||
315 reg_num==TAS3004_REG_ANALOG_CTRL) {
316 return tas_sync_byte_register(&self->super,
317 (uint)reg_num,
318 register_width(reg_num));
319 } else {
320 return tas_sync_register(&self->super,
321 (uint)reg_num,
322 register_width(reg_num));
323 }
324}
325
326static int
327tas3004_read_register( struct tas3004_data_t *self,
328 enum tas3004_reg_t reg_num,
329 char *data,
330 uint write_mode)
331{
332 return tas_read_register(&self->super,
333 (uint)reg_num,
334 register_width(reg_num),
335 data);
336}
337
338static inline int
339tas3004_fast_load(struct tas3004_data_t *self, int fast)
340{
341 if (fast)
342 self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
343 else
344 self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
345 return tas3004_sync_register(self,TAS3004_REG_MCR);
346}
347
348static uint
349tas3004_supported_mixers(struct tas3004_data_t *self)
350{
351 return SOUND_MASK_VOLUME |
352 SOUND_MASK_PCM |
353 SOUND_MASK_ALTPCM |
354 SOUND_MASK_IMIX |
355 SOUND_MASK_TREBLE |
356 SOUND_MASK_BASS |
357 SOUND_MASK_MIC |
358 SOUND_MASK_LINE;
359}
360
361static int
362tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
363{
364 switch(mixer) {
365 case SOUND_MIXER_VOLUME:
366 case SOUND_MIXER_PCM:
367 case SOUND_MIXER_ALTPCM:
368 case SOUND_MIXER_IMIX:
369 return 1;
370 default:
371 return 0;
372 }
373}
374
375static uint
376tas3004_stereo_mixers(struct tas3004_data_t *self)
377{
378 uint r = tas3004_supported_mixers(self);
379 uint i;
380
381 for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
382 if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
383 r &= ~(1<<i);
384 return r;
385}
386
387static int
388tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
389{
390 if (!self)
391 return -1;
392
393 *level = self->super.mixer[mixer];
394
395 return 0;
396}
397
398static int
399tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
400{
401 int rc;
402 tas_shadow_t *shadow;
403 uint temp;
404 uint offset=0;
405
406 if (!self)
407 return -1;
408
409 shadow = self->super.shadow;
410
411 if (!tas3004_mixer_is_stereo(self,mixer))
412 level = tas_mono_to_stereo(level);
413 switch(mixer) {
414 case SOUND_MIXER_VOLUME:
415 temp = tas3004_gain.master[level&0xff];
416 SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
417 temp = tas3004_gain.master[(level>>8)&0xff];
418 SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
419 rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
420 break;
421 case SOUND_MIXER_IMIX:
422 offset += 3;
423 case SOUND_MIXER_ALTPCM:
424 offset += 3;
425 case SOUND_MIXER_PCM:
426 /*
427 * Don't load these in fast mode. The documentation
428 * says it can be done in either mode, but testing it
429 * shows that fast mode produces ugly clicking.
430 */
431 /* tas3004_fast_load(self,1); */
432 temp = tas3004_gain.mixer[level&0xff];
433 SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
434 temp = tas3004_gain.mixer[(level>>8)&0xff];
435 SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
436 rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
437 if (rc == 0)
438 rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
439 /* tas3004_fast_load(self,0); */
440 break;
441 case SOUND_MIXER_TREBLE:
442 temp = tas3004_gain.treble[level&0xff];
443 shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
444 rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
445 break;
446 case SOUND_MIXER_BASS:
447 temp = tas3004_gain.bass[level&0xff];
448 shadow[TAS3004_REG_BASS][0]=temp&0xff;
449 rc = tas3004_sync_register(self,TAS3004_REG_BASS);
450 break;
451 case SOUND_MIXER_MIC:
452 if ((level&0xff)>0) {
453 software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
454 if (self->super.mixer[mixer] == 0) {
455 self->super.mixer[SOUND_MIXER_LINE] = 0;
456 shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
457 rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
458 } else rc=0;
459 } else {
460 self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
461 software_input_volume = SW_INPUT_VOLUME_SCALE *
462 (self->super.mixer[SOUND_MIXER_LINE]&0xff);
463 shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
464 rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
465 }
466 break;
467 case SOUND_MIXER_LINE:
468 if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
469 software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
470 rc=0;
471 }
472 break;
473 default:
474 rc = -1;
475 break;
476 }
477 if (rc < 0)
478 return rc;
479 self->super.mixer[mixer] = level;
480
481 return 0;
482}
483
484static int
485tas3004_leave_sleep(struct tas3004_data_t *self)
486{
487 unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
488
489 if (!self)
490 return -1;
491
492 /* Make sure something answers on the i2c bus */
493 if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
494 WRITE_NORMAL | FORCE_WRITE) < 0)
495 return -1;
496
497 tas3004_fast_load(self, 1);
498
499 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
500 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
501 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
502 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
503 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
504 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
505 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
506
507 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
508 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
509 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
510 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
511 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
512 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
513 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
514
515 tas3004_fast_load(self, 0);
516
517 (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
518 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
519 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
520 (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
521 (void)tas3004_sync_register(self,TAS3004_REG_BASS);
522 (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
523
524 return 0;
525}
526
527static int
528tas3004_enter_sleep(struct tas3004_data_t *self)
529{
530 if (!self)
531 return -1;
532 return 0;
533}
534
535static int
536tas3004_sync_biquad( struct tas3004_data_t *self,
537 u_int channel,
538 u_int filter)
539{
540 enum tas3004_reg_t reg;
541
542 if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
543 filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
544
545 reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
546
547 return tas3004_sync_register(self,reg);
548}
549
550static int
551tas3004_write_biquad_shadow( struct tas3004_data_t *self,
552 u_int channel,
553 u_int filter,
554 const union tas_biquad_t *biquad)
555{
556 tas_shadow_t *shadow=self->super.shadow;
557 enum tas3004_reg_t reg;
558
559 if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
560 filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
561
562 reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
563
564 SET_4_20(shadow[reg], 0,biquad->coeff.b0);
565 SET_4_20(shadow[reg], 3,biquad->coeff.b1);
566 SET_4_20(shadow[reg], 6,biquad->coeff.b2);
567 SET_4_20(shadow[reg], 9,biquad->coeff.a1);
568 SET_4_20(shadow[reg],12,biquad->coeff.a2);
569
570 return 0;
571}
572
573static int
574tas3004_write_biquad( struct tas3004_data_t *self,
575 u_int channel,
576 u_int filter,
577 const union tas_biquad_t *biquad)
578{
579 int rc;
580
581 rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
582 if (rc < 0) return rc;
583
584 return tas3004_sync_biquad(self, channel, filter);
585}
586
587static int
588tas3004_write_biquad_list( struct tas3004_data_t *self,
589 u_int filter_count,
590 u_int flags,
591 struct tas_biquad_ctrl_t *biquads)
592{
593 int i;
594 int rc;
595
596 if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
597
598 for (i=0; i<filter_count; i++) {
599 rc=tas3004_write_biquad(self,
600 biquads[i].channel,
601 biquads[i].filter,
602 &biquads[i].data);
603 if (rc < 0) break;
604 }
605
606 if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
607
608 return rc;
609}
610
611static int
612tas3004_read_biquad( struct tas3004_data_t *self,
613 u_int channel,
614 u_int filter,
615 union tas_biquad_t *biquad)
616{
617 tas_shadow_t *shadow=self->super.shadow;
618 enum tas3004_reg_t reg;
619
620 if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
621 filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
622
623 reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
624
625 biquad->coeff.b0=GET_4_20(shadow[reg], 0);
626 biquad->coeff.b1=GET_4_20(shadow[reg], 3);
627 biquad->coeff.b2=GET_4_20(shadow[reg], 6);
628 biquad->coeff.a1=GET_4_20(shadow[reg], 9);
629 biquad->coeff.a2=GET_4_20(shadow[reg],12);
630
631 return 0;
632}
633
634static int
635tas3004_eq_rw( struct tas3004_data_t *self,
636 u_int cmd,
637 u_long arg)
638{
639 void __user *argp = (void __user *)arg;
640 int rc;
641 struct tas_biquad_ctrl_t biquad;
642
643 if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
644 return -EFAULT;
645 }
646
647 if (cmd & SIOC_IN) {
648 rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
649 if (rc != 0) return rc;
650 }
651
652 if (cmd & SIOC_OUT) {
653 rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
654 if (rc != 0) return rc;
655
656 if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
657 return -EFAULT;
658 }
659
660 }
661 return 0;
662}
663
664static int
665tas3004_eq_list_rw( struct tas3004_data_t *self,
666 u_int cmd,
667 u_long arg)
668{
669 int rc = 0;
670 int filter_count;
671 int flags;
672 int i,j;
673 char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
674 struct tas_biquad_ctrl_t biquad;
675 struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
676
677 memset(sync_required,0,sizeof(sync_required));
678
679 if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
680 return -EFAULT;
681
682 if (copy_from_user(&flags, &argp->flags, sizeof(int)))
683 return -EFAULT;
684
685 if (cmd & SIOC_IN) {
686 }
687
688 for (i=0; i < filter_count; i++) {
689 if (copy_from_user(&biquad, &argp->biquads[i],
690 sizeof(struct tas_biquad_ctrl_t))) {
691 return -EFAULT;
692 }
693
694 if (cmd & SIOC_IN) {
695 sync_required[biquad.channel][biquad.filter]=1;
696 rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
697 if (rc != 0) return rc;
698 }
699
700 if (cmd & SIOC_OUT) {
701 rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
702 if (rc != 0) return rc;
703
704 if (copy_to_user(&argp->biquads[i], &biquad,
705 sizeof(struct tas_biquad_ctrl_t))) {
706 return -EFAULT;
707 }
708 }
709 }
710
711 if (cmd & SIOC_IN) {
712 /*
713 * This is OK for the tas3004. For the
714 * tas3001c, going into fast load mode causes
715 * the treble and bass to be reset to 0dB, and
716 * volume controls to be muted.
717 */
718 if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
719 for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
720 for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
721 if (sync_required[i][j]) {
722 rc=tas3004_sync_biquad(self, i, j);
723 if (rc < 0) goto out;
724 }
725 }
726 }
727 out:
728 if (flags & TAS_BIQUAD_FAST_LOAD)
729 tas3004_fast_load(self,0);
730 }
731
732 return rc;
733}
734
735static int
736tas3004_update_drce( struct tas3004_data_t *self,
737 int flags,
738 struct tas_drce_t *drce)
739{
740 tas_shadow_t *shadow;
741 int i;
742 shadow=self->super.shadow;
743
744 if (flags & TAS_DRCE_ABOVE_RATIO) {
745 self->drce_state.above.expand = drce->above.expand;
746 if (drce->above.val == (1<<8)) {
747 self->drce_state.above.val = 1<<8;
748 shadow[TAS3004_REG_DRC][0] = 0x02;
749
750 } else if (drce->above.expand) {
751 i=above_threshold_expansion_index(drce->above.val);
752 self->drce_state.above.val=above_threshold_expansion_ratio[i];
753 shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
754 } else {
755 i=above_threshold_compression_index(drce->above.val);
756 self->drce_state.above.val=above_threshold_compression_ratio[i];
757 shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
758 }
759 }
760
761 if (flags & TAS_DRCE_BELOW_RATIO) {
762 self->drce_state.below.expand = drce->below.expand;
763 if (drce->below.val == (1<<8)) {
764 self->drce_state.below.val = 1<<8;
765 shadow[TAS3004_REG_DRC][1] = 0x02;
766
767 } else if (drce->below.expand) {
768 i=below_threshold_expansion_index(drce->below.val);
769 self->drce_state.below.val=below_threshold_expansion_ratio[i];
770 shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
771 } else {
772 i=below_threshold_compression_index(drce->below.val);
773 self->drce_state.below.val=below_threshold_compression_ratio[i];
774 shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
775 }
776 }
777
778 if (flags & TAS_DRCE_THRESHOLD) {
779 self->drce_state.threshold=quantize_db(drce->threshold);
780 shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
781 }
782
783 if (flags & TAS_DRCE_ENERGY) {
784 i=time_index(drce->energy);
785 self->drce_state.energy=time_constants[i];
786 shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
787 }
788
789 if (flags & TAS_DRCE_ATTACK) {
790 i=time_index(drce->attack);
791 self->drce_state.attack=time_constants[i];
792 shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
793 }
794
795 if (flags & TAS_DRCE_DECAY) {
796 i=time_index(drce->decay);
797 self->drce_state.decay=time_constants[i];
798 shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
799 }
800
801 if (flags & TAS_DRCE_ENABLE) {
802 self->drce_state.enable = drce->enable;
803 }
804
805 if (!self->drce_state.enable) {
806 shadow[TAS3004_REG_DRC][0] |= 0x01;
807 }
808
809#ifdef DEBUG_DRCE
810 printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
811 self->drce_state.enable,
812 self->drce_state.above.expand,self->drce_state.above.val,
813 self->drce_state.below.expand,self->drce_state.below.val,
814 self->drce_state.threshold,
815 self->drce_state.energy,
816 self->drce_state.attack,
817 self->drce_state.decay);
818
819 printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
820 (unsigned char)shadow[TAS3004_REG_DRC][0],
821 (unsigned char)shadow[TAS3004_REG_DRC][1],
822 (unsigned char)shadow[TAS3004_REG_DRC][2],
823 (unsigned char)shadow[TAS3004_REG_DRC][3],
824 (unsigned char)shadow[TAS3004_REG_DRC][4],
825 (unsigned char)shadow[TAS3004_REG_DRC][5]);
826#endif
827
828 return tas3004_sync_register(self, TAS3004_REG_DRC);
829}
830
831static int
832tas3004_drce_rw( struct tas3004_data_t *self,
833 u_int cmd,
834 u_long arg)
835{
836 int rc;
837 struct tas_drce_ctrl_t drce_ctrl;
838 void __user *argp = (void __user *)arg;
839
840 if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
841 return -EFAULT;
842
843#ifdef DEBUG_DRCE
844 printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
845 drce_ctrl.flags,
846 drce_ctrl.data.enable,
847 drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
848 drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
849 drce_ctrl.data.threshold,
850 drce_ctrl.data.energy,
851 drce_ctrl.data.attack,
852 drce_ctrl.data.decay);
853#endif
854
855 if (cmd & SIOC_IN) {
856 rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
857 if (rc < 0) return rc;
858 }
859
860 if (cmd & SIOC_OUT) {
861 if (drce_ctrl.flags & TAS_DRCE_ENABLE)
862 drce_ctrl.data.enable = self->drce_state.enable;
863 if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
864 drce_ctrl.data.above = self->drce_state.above;
865 if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
866 drce_ctrl.data.below = self->drce_state.below;
867 if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
868 drce_ctrl.data.threshold = self->drce_state.threshold;
869 if (drce_ctrl.flags & TAS_DRCE_ENERGY)
870 drce_ctrl.data.energy = self->drce_state.energy;
871 if (drce_ctrl.flags & TAS_DRCE_ATTACK)
872 drce_ctrl.data.attack = self->drce_state.attack;
873 if (drce_ctrl.flags & TAS_DRCE_DECAY)
874 drce_ctrl.data.decay = self->drce_state.decay;
875
876 if (copy_to_user(argp, &drce_ctrl,
877 sizeof(struct tas_drce_ctrl_t))) {
878 return -EFAULT;
879 }
880 }
881
882 return 0;
883}
884
885static void
886tas3004_update_device_parameters(struct tas3004_data_t *self)
887{
888 char data;
889 int i;
890
891 if (!self) return;
892
893 if (self->output_id == TAS_OUTPUT_HEADPHONES) {
894 /* turn on allPass when headphones are plugged in */
895 data = 0x02;
896 } else {
897 data = 0x00;
898 }
899
900 tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
901
902 for (i=0; tas3004_eq_prefs[i]; i++) {
903 struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
904
905 if (eq->device_id == self->device_id &&
906 (eq->output_id == 0 || eq->output_id == self->output_id) &&
907 (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
908
909 tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
910 tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
911
912 break;
913 }
914 }
915}
916
917static void
918tas3004_device_change_handler(struct work_struct *work)
919{
920 struct tas3004_data_t *self;
921 self = container_of(work, struct tas3004_data_t, change);
922 tas3004_update_device_parameters(self);
923}
924
925static int
926tas3004_output_device_change( struct tas3004_data_t *self,
927 int device_id,
928 int output_id,
929 int speaker_id)
930{
931 self->device_id=device_id;
932 self->output_id=output_id;
933 self->speaker_id=speaker_id;
934
935 schedule_work(&self->change);
936
937 return 0;
938}
939
940static int
941tas3004_device_ioctl( struct tas3004_data_t *self,
942 u_int cmd,
943 u_long arg)
944{
945 uint __user *argp = (void __user *)arg;
946 switch (cmd) {
947 case TAS_READ_EQ:
948 case TAS_WRITE_EQ:
949 return tas3004_eq_rw(self, cmd, arg);
950
951 case TAS_READ_EQ_LIST:
952 case TAS_WRITE_EQ_LIST:
953 return tas3004_eq_list_rw(self, cmd, arg);
954
955 case TAS_READ_EQ_FILTER_COUNT:
956 put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
957 return 0;
958
959 case TAS_READ_EQ_CHANNEL_COUNT:
960 put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
961 return 0;
962
963 case TAS_READ_DRCE:
964 case TAS_WRITE_DRCE:
965 return tas3004_drce_rw(self, cmd, arg);
966
967 case TAS_READ_DRCE_CAPS:
968 put_user(TAS_DRCE_ENABLE |
969 TAS_DRCE_ABOVE_RATIO |
970 TAS_DRCE_BELOW_RATIO |
971 TAS_DRCE_THRESHOLD |
972 TAS_DRCE_ENERGY |
973 TAS_DRCE_ATTACK |
974 TAS_DRCE_DECAY,
975 argp);
976 return 0;
977
978 case TAS_READ_DRCE_MIN:
979 case TAS_READ_DRCE_MAX: {
980 struct tas_drce_ctrl_t drce_ctrl;
981 const struct tas_drce_t *drce_copy;
982
983 if (copy_from_user(&drce_ctrl, argp,
984 sizeof(struct tas_drce_ctrl_t))) {
985 return -EFAULT;
986 }
987
988 if (cmd == TAS_READ_DRCE_MIN) {
989 drce_copy=&tas3004_drce_min;
990 } else {
991 drce_copy=&tas3004_drce_max;
992 }
993
994 if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
995 drce_ctrl.data.above=drce_copy->above;
996 }
997 if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
998 drce_ctrl.data.below=drce_copy->below;
999 }
1000 if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
1001 drce_ctrl.data.threshold=drce_copy->threshold;
1002 }
1003 if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
1004 drce_ctrl.data.energy=drce_copy->energy;
1005 }
1006 if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
1007 drce_ctrl.data.attack=drce_copy->attack;
1008 }
1009 if (drce_ctrl.flags & TAS_DRCE_DECAY) {
1010 drce_ctrl.data.decay=drce_copy->decay;
1011 }
1012
1013 if (copy_to_user(argp, &drce_ctrl,
1014 sizeof(struct tas_drce_ctrl_t))) {
1015 return -EFAULT;
1016 }
1017 }
1018 }
1019
1020 return -EINVAL;
1021}
1022
1023static int
1024tas3004_init_mixer(struct tas3004_data_t *self)
1025{
1026 unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
1027
1028 /* Make sure something answers on the i2c bus */
1029 if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
1030 WRITE_NORMAL | FORCE_WRITE) < 0)
1031 return -1;
1032
1033 tas3004_fast_load(self, 1);
1034
1035 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
1036 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
1037 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
1038 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
1039 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
1040 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
1041 (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
1042
1043 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
1044 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
1045 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
1046 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
1047 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
1048 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
1049 (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
1050
1051 tas3004_sync_register(self, TAS3004_REG_DRC);
1052
1053 tas3004_sync_register(self, TAS3004_REG_MCR2);
1054
1055 tas3004_fast_load(self, 0);
1056
1057 tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
1058 tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
1059 tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
1060 tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
1061
1062 tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
1063 tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
1064
1065 tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
1066
1067 return 0;
1068}
1069
1070static int
1071tas3004_uninit_mixer(struct tas3004_data_t *self)
1072{
1073 tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
1074 tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
1075 tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
1076 tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
1077
1078 tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
1079 tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
1080
1081 tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
1082
1083 return 0;
1084}
1085
1086static int
1087tas3004_init(struct i2c_client *client)
1088{
1089 struct tas3004_data_t *self;
1090 size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
1091 char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
1092 char mcr2 = 0;
1093 int i, j;
1094
1095 self = kzalloc(sz, GFP_KERNEL);
1096 if (!self)
1097 return -ENOMEM;
1098
1099 self->super.client = client;
1100 self->super.shadow = (tas_shadow_t *)(self+1);
1101 self->output_id = TAS_OUTPUT_HEADPHONES;
1102
1103 dev_set_drvdata(&client->dev, self);
1104
1105 for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
1106 for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
1107 tas3004_write_biquad_shadow(self, i, j,
1108 &tas3004_eq_unity);
1109
1110 tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
1111 tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
1112
1113 INIT_WORK(&self->change, tas3004_device_change_handler);
1114 return 0;
1115}
1116
1117static void
1118tas3004_uninit(struct tas3004_data_t *self)
1119{
1120 tas3004_uninit_mixer(self);
1121 kfree(self);
1122}
1123
1124
1125struct tas_driver_hooks_t tas3004_hooks = {
1126 .init = (tas_hook_init_t)tas3004_init,
1127 .post_init = (tas_hook_post_init_t)tas3004_init_mixer,
1128 .uninit = (tas_hook_uninit_t)tas3004_uninit,
1129 .get_mixer_level = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
1130 .set_mixer_level = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
1131 .enter_sleep = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
1132 .leave_sleep = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
1133 .supported_mixers = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
1134 .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
1135 .stereo_mixers = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
1136 .output_device_change = (tas_hook_output_device_change_t)tas3004_output_device_change,
1137 .device_ioctl = (tas_hook_device_ioctl_t)tas3004_device_ioctl
1138};
diff --git a/sound/oss/dmasound/tas3004.h b/sound/oss/dmasound/tas3004.h
deleted file mode 100644
index c6d584bf2ca4..000000000000
--- a/sound/oss/dmasound/tas3004.h
+++ /dev/null
@@ -1,77 +0,0 @@
1/*
2 * Header file for the i2c/i2s based TA3004 sound chip used
3 * on some Apple hardware. Also known as "tumbler".
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file COPYING in the main directory of this archive
7 * for more details.
8 *
9 * Written by Christopher C. Chimelis <chris@debian.org>
10 */
11
12#ifndef _TAS3004_H_
13#define _TAS3004_H_
14
15#include <linux/types.h>
16
17#include "tas_common.h"
18#include "tas_eq_prefs.h"
19
20/*
21 * Macros that correspond to the registers that we write to
22 * when setting the various values.
23 */
24
25#define TAS3004_VERSION "0.3"
26#define TAS3004_DATE "20011214"
27
28#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
29#define I2C_DRIVERID_TAS3004 (I2C_DRIVERID_TAS_BASE+1)
30
31extern struct tas_driver_hooks_t tas3004_hooks;
32extern struct tas_gain_t tas3004_gain;
33extern struct tas_eq_pref_t *tas3004_eq_prefs[];
34
35enum tas3004_reg_t {
36 TAS3004_REG_MCR = 0x01,
37 TAS3004_REG_DRC = 0x02,
38
39 TAS3004_REG_VOLUME = 0x04,
40 TAS3004_REG_TREBLE = 0x05,
41 TAS3004_REG_BASS = 0x06,
42 TAS3004_REG_LEFT_MIXER = 0x07,
43 TAS3004_REG_RIGHT_MIXER = 0x08,
44
45 TAS3004_REG_LEFT_BIQUAD0 = 0x0a,
46 TAS3004_REG_LEFT_BIQUAD1 = 0x0b,
47 TAS3004_REG_LEFT_BIQUAD2 = 0x0c,
48 TAS3004_REG_LEFT_BIQUAD3 = 0x0d,
49 TAS3004_REG_LEFT_BIQUAD4 = 0x0e,
50 TAS3004_REG_LEFT_BIQUAD5 = 0x0f,
51 TAS3004_REG_LEFT_BIQUAD6 = 0x10,
52
53 TAS3004_REG_RIGHT_BIQUAD0 = 0x13,
54 TAS3004_REG_RIGHT_BIQUAD1 = 0x14,
55 TAS3004_REG_RIGHT_BIQUAD2 = 0x15,
56 TAS3004_REG_RIGHT_BIQUAD3 = 0x16,
57 TAS3004_REG_RIGHT_BIQUAD4 = 0x17,
58 TAS3004_REG_RIGHT_BIQUAD5 = 0x18,
59 TAS3004_REG_RIGHT_BIQUAD6 = 0x19,
60
61 TAS3004_REG_LEFT_LOUD_BIQUAD = 0x21,
62 TAS3004_REG_RIGHT_LOUD_BIQUAD = 0x22,
63
64 TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN = 0x23,
65 TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
66
67 TAS3004_REG_TEST = 0x29,
68
69 TAS3004_REG_ANALOG_CTRL = 0x40,
70 TAS3004_REG_TEST1 = 0x41,
71 TAS3004_REG_TEST2 = 0x42,
72 TAS3004_REG_MCR2 = 0x43,
73
74 TAS3004_REG_MAX = 0x44
75};
76
77#endif /* _TAS3004_H_ */
diff --git a/sound/oss/dmasound/tas3004_tables.c b/sound/oss/dmasound/tas3004_tables.c
deleted file mode 100644
index b910e0a66775..000000000000
--- a/sound/oss/dmasound/tas3004_tables.c
+++ /dev/null
@@ -1,301 +0,0 @@
1#include "tas3004.h"
2#include "tas_eq_prefs.h"
3
4static struct tas_drce_t eqp_17_1_0_drce={
5 .enable = 1,
6 .above = { .val = 3.0 * (1<<8), .expand = 0 },
7 .below = { .val = 1.0 * (1<<8), .expand = 0 },
8 .threshold = -19.12 * (1<<8),
9 .energy = 2.4 * (1<<12),
10 .attack = 0.013 * (1<<12),
11 .decay = 0.212 * (1<<12),
12};
13
14static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
15 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
16 { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
17 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
18 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
19 { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
20 { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
21 { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
22
23 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
24 { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
25 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
26 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
27 { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
28 { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
29 { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
30};
31
32static struct tas_eq_pref_t eqp_17_1_0 = {
33 .sample_rate = 44100,
34 .device_id = 0x17,
35 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
36 .speaker_id = 0x00,
37
38 .drce = &eqp_17_1_0_drce,
39
40 .filter_count = 14,
41 .biquads = eqp_17_1_0_biquads
42};
43
44/* ======================================================================== */
45
46static struct tas_drce_t eqp_18_1_0_drce={
47 .enable = 1,
48 .above = { .val = 3.0 * (1<<8), .expand = 0 },
49 .below = { .val = 1.0 * (1<<8), .expand = 0 },
50 .threshold = -13.14 * (1<<8),
51 .energy = 2.4 * (1<<12),
52 .attack = 0.013 * (1<<12),
53 .decay = 0.212 * (1<<12),
54};
55
56static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
57 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
58 { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
59 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
60 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
61 { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
62 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
63 { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
64
65 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
66 { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
67 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
68 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
69 { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
70 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
71 { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
72};
73
74static struct tas_eq_pref_t eqp_18_1_0 = {
75 .sample_rate = 44100,
76 .device_id = 0x18,
77 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
78 .speaker_id = 0x00,
79
80 .drce = &eqp_18_1_0_drce,
81
82 .filter_count = 14,
83 .biquads = eqp_18_1_0_biquads
84};
85
86/* ======================================================================== */
87
88static struct tas_drce_t eqp_1a_1_0_drce={
89 .enable = 1,
90 .above = { .val = 3.0 * (1<<8), .expand = 0 },
91 .below = { .val = 1.0 * (1<<8), .expand = 0 },
92 .threshold = -10.75 * (1<<8),
93 .energy = 2.4 * (1<<12),
94 .attack = 0.013 * (1<<12),
95 .decay = 0.212 * (1<<12),
96};
97
98static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
99 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
100 { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
101 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
102 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
103 { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
104 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
105 { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
106
107 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
108 { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
109 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
110 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
111 { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
112 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
113 { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
114};
115
116static struct tas_eq_pref_t eqp_1a_1_0 = {
117 .sample_rate = 44100,
118 .device_id = 0x1a,
119 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
120 .speaker_id = 0x00,
121
122 .drce = &eqp_1a_1_0_drce,
123
124 .filter_count = 14,
125 .biquads = eqp_1a_1_0_biquads
126};
127
128/* ======================================================================== */
129
130static struct tas_drce_t eqp_1c_1_0_drce={
131 .enable = 1,
132 .above = { .val = 3.0 * (1<<8), .expand = 0 },
133 .below = { .val = 1.0 * (1<<8), .expand = 0 },
134 .threshold = -14.34 * (1<<8),
135 .energy = 2.4 * (1<<12),
136 .attack = 0.013 * (1<<12),
137 .decay = 0.212 * (1<<12),
138};
139
140static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
141 { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
142 { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
143 { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
144 { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
145 { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
146 { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
147 { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
148
149 { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
150 { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
151 { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
152 { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
153 { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
154 { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
155 { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
156};
157
158static struct tas_eq_pref_t eqp_1c_1_0 = {
159 .sample_rate = 44100,
160 .device_id = 0x1c,
161 .output_id = TAS_OUTPUT_INTERNAL_SPKR,
162 .speaker_id = 0x00,
163
164 .drce = &eqp_1c_1_0_drce,
165
166 .filter_count = 14,
167 .biquads = eqp_1c_1_0_biquads
168};
169
170/* ======================================================================== */
171
172static uint tas3004_master_tab[]={
173 0x0, 0x75, 0x9c, 0xbb,
174 0xdb, 0xfb, 0x11e, 0x143,
175 0x16b, 0x196, 0x1c3, 0x1f5,
176 0x229, 0x263, 0x29f, 0x2e1,
177 0x328, 0x373, 0x3c5, 0x41b,
178 0x478, 0x4dc, 0x547, 0x5b8,
179 0x633, 0x6b5, 0x740, 0x7d5,
180 0x873, 0x91c, 0x9d2, 0xa92,
181 0xb5e, 0xc39, 0xd22, 0xe19,
182 0xf20, 0x1037, 0x1161, 0x129e,
183 0x13ed, 0x1551, 0x16ca, 0x185d,
184 0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
185 0x21c1, 0x23fa, 0x2655, 0x28d6,
186 0x2b7c, 0x2e4a, 0x3141, 0x3464,
187 0x37b4, 0x3b35, 0x3ee9, 0x42d3,
188 0x46f6, 0x4b53, 0x4ff0, 0x54ce,
189 0x59f2, 0x5f5f, 0x6519, 0x6b24,
190 0x7183, 0x783c, 0x7f53, 0x86cc,
191 0x8ead, 0x96fa, 0x9fba, 0xa8f2,
192 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
193 0xdee8, 0xeb75, 0xf8aa, 0x1068e,
194 0x1152a, 0x12487, 0x134ad, 0x145a5,
195 0x1577b, 0x16a37, 0x17df5, 0x192bd,
196 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
197 0x20b55, 0x22727, 0x24456, 0x262f2,
198 0x2830b
199};
200
201static uint tas3004_mixer_tab[]={
202 0x0, 0x748, 0x9be, 0xbaf,
203 0xda4, 0xfb1, 0x11de, 0x1431,
204 0x16ad, 0x1959, 0x1c37, 0x1f4b,
205 0x2298, 0x2628, 0x29fb, 0x2e12,
206 0x327d, 0x3734, 0x3c47, 0x41b4,
207 0x4787, 0x4dbe, 0x546d, 0x5b86,
208 0x632e, 0x6b52, 0x7400, 0x7d54,
209 0x873b, 0x91c6, 0x9d1a, 0xa920,
210 0xb5e5, 0xc38c, 0xd21b, 0xe18f,
211 0xf1f5, 0x1036a, 0x1160f, 0x129d6,
212 0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
213 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
214 0x21c0f, 0x23fa3, 0x26552, 0x28d64,
215 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
216 0x37b44, 0x3b353, 0x3ee94, 0x42d30,
217 0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
218 0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
219 0x71835, 0x783c3, 0x7f52c, 0x86cc0,
220 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
221 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
222 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
223 0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
224 0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
225 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
226 0x20b542, 0x227268, 0x244564, 0x262f26,
227 0x2830af
228};
229
230static uint tas3004_treble_tab[]={
231 0x96, 0x95, 0x95, 0x94,
232 0x93, 0x92, 0x92, 0x91,
233 0x90, 0x90, 0x8f, 0x8e,
234 0x8d, 0x8d, 0x8c, 0x8b,
235 0x8a, 0x8a, 0x89, 0x88,
236 0x88, 0x87, 0x86, 0x85,
237 0x85, 0x84, 0x83, 0x83,
238 0x82, 0x81, 0x80, 0x80,
239 0x7f, 0x7e, 0x7e, 0x7d,
240 0x7c, 0x7b, 0x7b, 0x7a,
241 0x79, 0x78, 0x78, 0x77,
242 0x76, 0x76, 0x75, 0x74,
243 0x73, 0x73, 0x72, 0x71,
244 0x71, 0x68, 0x45, 0x5b,
245 0x6d, 0x6c, 0x6b, 0x6a,
246 0x69, 0x68, 0x67, 0x66,
247 0x65, 0x63, 0x62, 0x62,
248 0x60, 0x5e, 0x5c, 0x5b,
249 0x59, 0x57, 0x55, 0x53,
250 0x52, 0x4f, 0x4d, 0x4a,
251 0x48, 0x46, 0x43, 0x40,
252 0x3d, 0x3a, 0x36, 0x33,
253 0x2f, 0x2c, 0x27, 0x23,
254 0x1f, 0x1a, 0x15, 0xf,
255 0x8, 0x5, 0x2, 0x1,
256 0x1
257};
258
259static uint tas3004_bass_tab[]={
260 0x96, 0x95, 0x95, 0x94,
261 0x93, 0x92, 0x92, 0x91,
262 0x90, 0x90, 0x8f, 0x8e,
263 0x8d, 0x8d, 0x8c, 0x8b,
264 0x8a, 0x8a, 0x89, 0x88,
265 0x88, 0x87, 0x86, 0x85,
266 0x85, 0x84, 0x83, 0x83,
267 0x82, 0x81, 0x80, 0x80,
268 0x7f, 0x7e, 0x7e, 0x7d,
269 0x7c, 0x7b, 0x7b, 0x7a,
270 0x79, 0x78, 0x78, 0x77,
271 0x76, 0x76, 0x75, 0x74,
272 0x73, 0x73, 0x72, 0x71,
273 0x70, 0x6f, 0x6e, 0x6d,
274 0x6c, 0x6b, 0x6a, 0x6a,
275 0x69, 0x67, 0x66, 0x66,
276 0x65, 0x63, 0x62, 0x62,
277 0x61, 0x60, 0x5e, 0x5d,
278 0x5b, 0x59, 0x57, 0x55,
279 0x53, 0x51, 0x4f, 0x4c,
280 0x4a, 0x48, 0x46, 0x44,
281 0x41, 0x3e, 0x3b, 0x38,
282 0x36, 0x33, 0x2f, 0x2b,
283 0x28, 0x24, 0x20, 0x1c,
284 0x17, 0x12, 0xd, 0x7,
285 0x1
286};
287
288struct tas_gain_t tas3004_gain={
289 .master = tas3004_master_tab,
290 .treble = tas3004_treble_tab,
291 .bass = tas3004_bass_tab,
292 .mixer = tas3004_mixer_tab
293};
294
295struct tas_eq_pref_t *tas3004_eq_prefs[]={
296 &eqp_17_1_0,
297 &eqp_18_1_0,
298 &eqp_1a_1_0,
299 &eqp_1c_1_0,
300 NULL
301};
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
deleted file mode 100644
index b295ef682192..000000000000
--- a/sound/oss/dmasound/tas_common.c
+++ /dev/null
@@ -1,214 +0,0 @@
1#include <linux/module.h>
2#include <linux/slab.h>
3#include <linux/proc_fs.h>
4#include <linux/ioport.h>
5#include <linux/sysctl.h>
6#include <linux/types.h>
7#include <linux/i2c.h>
8#include <linux/init.h>
9#include <linux/soundcard.h>
10#include <asm/uaccess.h>
11#include <asm/errno.h>
12#include <asm/io.h>
13#include <asm/prom.h>
14
15#include "tas_common.h"
16
17#define CALL0(proc) \
18 do { \
19 struct tas_data_t *self; \
20 if (!tas_client || driver_hooks == NULL) \
21 return -1; \
22 self = dev_get_drvdata(&tas_client->dev); \
23 if (driver_hooks->proc) \
24 return driver_hooks->proc(self); \
25 else \
26 return -EINVAL; \
27 } while (0)
28
29#define CALL(proc,arg...) \
30 do { \
31 struct tas_data_t *self; \
32 if (!tas_client || driver_hooks == NULL) \
33 return -1; \
34 self = dev_get_drvdata(&tas_client->dev); \
35 if (driver_hooks->proc) \
36 return driver_hooks->proc(self, ## arg); \
37 else \
38 return -EINVAL; \
39 } while (0)
40
41
42static u8 tas_i2c_address = 0x34;
43static struct i2c_client *tas_client;
44
45static int tas_attach_adapter(struct i2c_adapter *);
46static int tas_detach_client(struct i2c_client *);
47
48struct i2c_driver tas_driver = {
49 .driver = {
50 .name = "tas",
51 },
52 .attach_adapter = tas_attach_adapter,
53 .detach_client = tas_detach_client,
54};
55
56struct tas_driver_hooks_t *driver_hooks;
57
58int
59tas_register_driver(struct tas_driver_hooks_t *hooks)
60{
61 driver_hooks = hooks;
62 return 0;
63}
64
65int
66tas_get_mixer_level(int mixer, uint *level)
67{
68 CALL(get_mixer_level,mixer,level);
69}
70
71int
72tas_set_mixer_level(int mixer,uint level)
73{
74 CALL(set_mixer_level,mixer,level);
75}
76
77int
78tas_enter_sleep(void)
79{
80 CALL0(enter_sleep);
81}
82
83int
84tas_leave_sleep(void)
85{
86 CALL0(leave_sleep);
87}
88
89int
90tas_supported_mixers(void)
91{
92 CALL0(supported_mixers);
93}
94
95int
96tas_mixer_is_stereo(int mixer)
97{
98 CALL(mixer_is_stereo,mixer);
99}
100
101int
102tas_stereo_mixers(void)
103{
104 CALL0(stereo_mixers);
105}
106
107int
108tas_output_device_change(int device_id,int layout_id,int speaker_id)
109{
110 CALL(output_device_change,device_id,layout_id,speaker_id);
111}
112
113int
114tas_device_ioctl(u_int cmd, u_long arg)
115{
116 CALL(device_ioctl,cmd,arg);
117}
118
119int
120tas_post_init(void)
121{
122 CALL0(post_init);
123}
124
125static int
126tas_detect_client(struct i2c_adapter *adapter, int address)
127{
128 static const char *client_name = "tas Digital Equalizer";
129 struct i2c_client *new_client;
130 int rc = -ENODEV;
131
132 if (!driver_hooks) {
133 printk(KERN_ERR "tas_detect_client called with no hooks !\n");
134 return -ENODEV;
135 }
136
137 new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
138 if (!new_client)
139 return -ENOMEM;
140
141 new_client->addr = address;
142 new_client->adapter = adapter;
143 new_client->driver = &tas_driver;
144 strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
145
146 if (driver_hooks->init(new_client))
147 goto bail;
148
149 /* Tell the i2c layer a new client has arrived */
150 if (i2c_attach_client(new_client)) {
151 driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
152 goto bail;
153 }
154
155 tas_client = new_client;
156 return 0;
157 bail:
158 tas_client = NULL;
159 kfree(new_client);
160 return rc;
161}
162
163static int
164tas_attach_adapter(struct i2c_adapter *adapter)
165{
166 if (!strncmp(adapter->name, "mac-io", 6))
167 return tas_detect_client(adapter, tas_i2c_address);
168 return 0;
169}
170
171static int
172tas_detach_client(struct i2c_client *client)
173{
174 if (client == tas_client) {
175 driver_hooks->uninit(dev_get_drvdata(&client->dev));
176
177 i2c_detach_client(client);
178 kfree(client);
179 }
180 return 0;
181}
182
183void
184tas_cleanup(void)
185{
186 i2c_del_driver(&tas_driver);
187}
188
189int __init
190tas_init(int driver_id, const char *driver_name)
191{
192 const u32* paddr;
193 struct device_node *tas_node;
194
195 printk(KERN_INFO "tas driver [%s])\n", driver_name);
196
197#ifndef CONFIG_I2C_POWERMAC
198 request_module("i2c-powermac");
199#endif
200 tas_node = of_find_node_by_name("deq");
201 if (tas_node == NULL)
202 return -ENODEV;
203 paddr = of_get_property(tas_node, "i2c-address", NULL);
204 if (paddr) {
205 tas_i2c_address = (*paddr) >> 1;
206 printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
207 tas_i2c_address);
208 } else
209 printk(KERN_INFO "using i2c address: 0x%x (default)\n",
210 tas_i2c_address);
211 of_node_put(tas_node);
212
213 return i2c_add_driver(&tas_driver);
214}
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h
deleted file mode 100644
index 0741c28e56ce..000000000000
--- a/sound/oss/dmasound/tas_common.h
+++ /dev/null
@@ -1,284 +0,0 @@
1#ifndef _TAS_COMMON_H_
2#define _TAS_COMMON_H_
3
4#include <linux/i2c.h>
5#include <linux/soundcard.h>
6#include <asm/string.h>
7
8#define I2C_DRIVERID_TAS_BASE (0xFEBA)
9
10#define SET_4_20(shadow, offset, val) \
11 do { \
12 (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
13 (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \
14 (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \
15 } while (0)
16
17#define GET_4_20(shadow, offset) \
18 (((u_int)((shadow)[(offset)+0]) << 16) | \
19 ((u_int)((shadow)[(offset)+1]) << 8) | \
20 ((u_int)((shadow)[(offset)+2]) << 0))
21
22
23#define TAS_BIQUAD_FAST_LOAD 0x01
24
25#define TAS_DRCE_ENABLE 0x01
26#define TAS_DRCE_ABOVE_RATIO 0x02
27#define TAS_DRCE_BELOW_RATIO 0x04
28#define TAS_DRCE_THRESHOLD 0x08
29#define TAS_DRCE_ENERGY 0x10
30#define TAS_DRCE_ATTACK 0x20
31#define TAS_DRCE_DECAY 0x40
32
33#define TAS_DRCE_ALL 0x7f
34
35
36#define TAS_OUTPUT_HEADPHONES 0x00
37#define TAS_OUTPUT_INTERNAL_SPKR 0x01
38#define TAS_OUTPUT_EXTERNAL_SPKR 0x02
39
40
41union tas_biquad_t {
42 struct {
43 int b0,b1,b2,a1,a2;
44 } coeff;
45 int buf[5];
46};
47
48struct tas_biquad_ctrl_t {
49 u_int channel:4;
50 u_int filter:4;
51
52 union tas_biquad_t data;
53};
54
55struct tas_biquad_ctrl_list_t {
56 int flags;
57 int filter_count;
58 struct tas_biquad_ctrl_t biquads[0];
59};
60
61struct tas_ratio_t {
62 unsigned short val; /* 8.8 */
63 unsigned short expand; /* 0 = compress, !0 = expand. */
64};
65
66struct tas_drce_t {
67 unsigned short enable;
68 struct tas_ratio_t above;
69 struct tas_ratio_t below;
70 short threshold; /* dB, 8.8 signed */
71 unsigned short energy; /* seconds, 4.12 unsigned */
72 unsigned short attack; /* seconds, 4.12 unsigned */
73 unsigned short decay; /* seconds, 4.12 unsigned */
74};
75
76struct tas_drce_ctrl_t {
77 uint flags;
78
79 struct tas_drce_t data;
80};
81
82struct tas_gain_t
83{
84 unsigned int *master;
85 unsigned int *treble;
86 unsigned int *bass;
87 unsigned int *mixer;
88};
89
90typedef char tas_shadow_t[0x45];
91
92struct tas_data_t
93{
94 struct i2c_client *client;
95 tas_shadow_t *shadow;
96 uint mixer[SOUND_MIXER_NRDEVICES];
97};
98
99typedef int (*tas_hook_init_t)(struct i2c_client *);
100typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
101typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
102
103typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
104typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
105
106typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
107typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
108
109typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
110typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
111typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
112
113typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
114typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
115
116struct tas_driver_hooks_t {
117 /*
118 * All hardware initialisation must be performed in
119 * post_init(), as tas_dmasound_init() does a hardware reset.
120 *
121 * init() is called before tas_dmasound_init() so that
122 * ouput_device_change() is always called after i2c driver
123 * initialisation. The implication is that
124 * output_device_change() must cope with the fact that it
125 * may be called before post_init().
126 */
127
128 tas_hook_init_t init;
129 tas_hook_post_init_t post_init;
130 tas_hook_uninit_t uninit;
131
132 tas_hook_get_mixer_level_t get_mixer_level;
133 tas_hook_set_mixer_level_t set_mixer_level;
134
135 tas_hook_enter_sleep_t enter_sleep;
136 tas_hook_leave_sleep_t leave_sleep;
137
138 tas_hook_supported_mixers_t supported_mixers;
139 tas_hook_mixer_is_stereo_t mixer_is_stereo;
140 tas_hook_stereo_mixers_t stereo_mixers;
141
142 tas_hook_output_device_change_t output_device_change;
143 tas_hook_device_ioctl_t device_ioctl;
144};
145
146enum tas_write_mode_t {
147 WRITE_HW = 0x01,
148 WRITE_SHADOW = 0x02,
149 WRITE_NORMAL = 0x03,
150 FORCE_WRITE = 0x04
151};
152
153static inline uint
154tas_mono_to_stereo(uint mono)
155{
156 mono &=0xff;
157 return mono | (mono<<8);
158}
159
160/*
161 * Todo: make these functions a bit more efficient !
162 */
163static inline int
164tas_write_register( struct tas_data_t *self,
165 uint reg_num,
166 uint reg_width,
167 char *data,
168 uint write_mode)
169{
170 int rc;
171
172 if (reg_width==0 || data==NULL || self==NULL)
173 return -EINVAL;
174 if (!(write_mode & FORCE_WRITE) &&
175 !memcmp(data,self->shadow[reg_num],reg_width))
176 return 0;
177
178 if (write_mode & WRITE_SHADOW)
179 memcpy(self->shadow[reg_num],data,reg_width);
180 if (write_mode & WRITE_HW) {
181 rc=i2c_smbus_write_i2c_block_data(self->client,
182 reg_num,
183 reg_width,
184 data);
185 if (rc < 0) {
186 printk("tas: I2C block write failed \n");
187 return rc;
188 }
189 }
190 return 0;
191}
192
193static inline int
194tas_sync_register( struct tas_data_t *self,
195 uint reg_num,
196 uint reg_width)
197{
198 int rc;
199
200 if (reg_width==0 || self==NULL)
201 return -EINVAL;
202 rc=i2c_smbus_write_i2c_block_data(self->client,
203 reg_num,
204 reg_width,
205 self->shadow[reg_num]);
206 if (rc < 0) {
207 printk("tas: I2C block write failed \n");
208 return rc;
209 }
210 return 0;
211}
212
213static inline int
214tas_write_byte_register( struct tas_data_t *self,
215 uint reg_num,
216 char data,
217 uint write_mode)
218{
219 if (self==NULL)
220 return -1;
221 if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
222 return 0;
223 if (write_mode & WRITE_SHADOW)
224 self->shadow[reg_num][0]=data;
225 if (write_mode & WRITE_HW) {
226 if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
227 printk("tas: I2C byte write failed \n");
228 return -1;
229 }
230 }
231 return 0;
232}
233
234static inline int
235tas_sync_byte_register( struct tas_data_t *self,
236 uint reg_num,
237 uint reg_width)
238{
239 if (reg_width==0 || self==NULL)
240 return -1;
241 if (i2c_smbus_write_byte_data(
242 self->client, reg_num, self->shadow[reg_num][0]) < 0) {
243 printk("tas: I2C byte write failed \n");
244 return -1;
245 }
246 return 0;
247}
248
249static inline int
250tas_read_register( struct tas_data_t *self,
251 uint reg_num,
252 uint reg_width,
253 char *data)
254{
255 if (reg_width==0 || data==NULL || self==NULL)
256 return -1;
257 memcpy(data,self->shadow[reg_num],reg_width);
258 return 0;
259}
260
261extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
262
263extern int tas_get_mixer_level(int mixer,uint *level);
264extern int tas_set_mixer_level(int mixer,uint level);
265extern int tas_enter_sleep(void);
266extern int tas_leave_sleep(void);
267extern int tas_supported_mixers(void);
268extern int tas_mixer_is_stereo(int mixer);
269extern int tas_stereo_mixers(void);
270extern int tas_output_device_change(int,int,int);
271extern int tas_device_ioctl(u_int, u_long);
272
273extern void tas_cleanup(void);
274extern int tas_init(int driver_id,const char *driver_name);
275extern int tas_post_init(void);
276
277#endif /* _TAS_COMMON_H_ */
278/*
279 * Local Variables:
280 * tab-width: 8
281 * indent-tabs-mode: t
282 * c-basic-offset: 8
283 * End:
284 */
diff --git a/sound/oss/dmasound/tas_eq_prefs.h b/sound/oss/dmasound/tas_eq_prefs.h
deleted file mode 100644
index 3a994eda6abc..000000000000
--- a/sound/oss/dmasound/tas_eq_prefs.h
+++ /dev/null
@@ -1,24 +0,0 @@
1#ifndef _TAS_EQ_PREFS_H_
2#define _TAS_EQ_PREFS_H_
3
4struct tas_eq_pref_t {
5 u_int sample_rate;
6 u_int device_id;
7 u_int output_id;
8 u_int speaker_id;
9
10 struct tas_drce_t *drce;
11
12 u_int filter_count;
13 struct tas_biquad_ctrl_t *biquads;
14};
15
16#endif /* _TAS_EQ_PREFS_H_ */
17
18/*
19 * Local Variables:
20 * tab-width: 8
21 * indent-tabs-mode: t
22 * c-basic-offset: 8
23 * End:
24 */
diff --git a/sound/oss/dmasound/tas_ioctl.h b/sound/oss/dmasound/tas_ioctl.h
deleted file mode 100644
index 9d12b373b4a9..000000000000
--- a/sound/oss/dmasound/tas_ioctl.h
+++ /dev/null
@@ -1,23 +0,0 @@
1#ifndef _TAS_IOCTL_H_
2#define _TAS_IOCTL_H_
3
4#include <linux/soundcard.h>
5
6
7#define TAS_READ_EQ _SIOR('t',0,struct tas_biquad_ctrl_t)
8#define TAS_WRITE_EQ _SIOW('t',0,struct tas_biquad_ctrl_t)
9
10#define TAS_READ_EQ_LIST _SIOR('t',1,struct tas_biquad_ctrl_t)
11#define TAS_WRITE_EQ_LIST _SIOW('t',1,struct tas_biquad_ctrl_t)
12
13#define TAS_READ_EQ_FILTER_COUNT _SIOR('t',2,int)
14#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
15
16#define TAS_READ_DRCE _SIOR('t',4,struct tas_drce_ctrl_t)
17#define TAS_WRITE_DRCE _SIOW('t',4,struct tas_drce_ctrl_t)
18
19#define TAS_READ_DRCE_CAPS _SIOR('t',5,int)
20#define TAS_READ_DRCE_MIN _SIOR('t',6,int)
21#define TAS_READ_DRCE_MAX _SIOR('t',7,int)
22
23#endif
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c
deleted file mode 100644
index ca973ac2a30a..000000000000
--- a/sound/oss/dmasound/trans_16.c
+++ /dev/null
@@ -1,898 +0,0 @@
1/*
2 * linux/sound/oss/dmasound/trans_16.c
3 *
4 * 16 bit translation routines. Only used by Power mac at present.
5 *
6 * See linux/sound/oss/dmasound/dmasound_core.c for copyright and
7 * history prior to 08/02/2001.
8 *
9 * 08/02/2001 Iain Sandoe
10 * split from dmasound_awacs.c
11 * 11/29/2003 Renzo Davoli (King Enzo)
12 * - input resampling (for soft rate < hard rate)
13 * - software line in gain control
14 */
15
16#include <linux/soundcard.h>
17#include <asm/uaccess.h>
18#include "dmasound.h"
19
20extern int expand_bal; /* Balance factor for expanding (not volume!) */
21static short dmasound_alaw2dma16[] ;
22static short dmasound_ulaw2dma16[] ;
23
24static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
25 u_char frame[], ssize_t *frameUsed,
26 ssize_t frameLeft);
27static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
28 u_char frame[], ssize_t *frameUsed,
29 ssize_t frameLeft);
30static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
31 u_char frame[], ssize_t *frameUsed,
32 ssize_t frameLeft);
33static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
34 u_char frame[], ssize_t *frameUsed,
35 ssize_t frameLeft);
36static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
37 u_char frame[], ssize_t *frameUsed,
38 ssize_t frameLeft);
39
40static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
41 u_char frame[], ssize_t *frameUsed,
42 ssize_t frameLeft);
43static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
44 u_char frame[], ssize_t *frameUsed,
45 ssize_t frameLeft);
46static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
47 u_char frame[], ssize_t *frameUsed,
48 ssize_t frameLeft);
49static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
50 u_char frame[], ssize_t *frameUsed,
51 ssize_t frameLeft);
52static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
53 u_char frame[], ssize_t *frameUsed,
54 ssize_t frameLeft);
55
56static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
57 u_char frame[], ssize_t *frameUsed,
58 ssize_t frameLeft);
59static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
60 u_char frame[], ssize_t *frameUsed,
61 ssize_t frameLeft);
62
63/*** Translations ************************************************************/
64
65static int expand_data; /* Data for expanding */
66
67static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
68 u_char frame[], ssize_t *frameUsed,
69 ssize_t frameLeft)
70{
71 short *table = dmasound.soft.format == AFMT_MU_LAW
72 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
73 ssize_t count, used;
74 short *p = (short *) &frame[*frameUsed];
75 int val, stereo = dmasound.soft.stereo;
76
77 frameLeft >>= 2;
78 if (stereo)
79 userCount >>= 1;
80 used = count = min_t(unsigned long, userCount, frameLeft);
81 while (count > 0) {
82 u_char data;
83 if (get_user(data, userPtr++))
84 return -EFAULT;
85 val = table[data];
86 *p++ = val;
87 if (stereo) {
88 if (get_user(data, userPtr++))
89 return -EFAULT;
90 val = table[data];
91 }
92 *p++ = val;
93 count--;
94 }
95 *frameUsed += used * 4;
96 return stereo? used * 2: used;
97}
98
99
100static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
101 u_char frame[], ssize_t *frameUsed,
102 ssize_t frameLeft)
103{
104 ssize_t count, used;
105 short *p = (short *) &frame[*frameUsed];
106 int val, stereo = dmasound.soft.stereo;
107
108 frameLeft >>= 2;
109 if (stereo)
110 userCount >>= 1;
111 used = count = min_t(unsigned long, userCount, frameLeft);
112 while (count > 0) {
113 u_char data;
114 if (get_user(data, userPtr++))
115 return -EFAULT;
116 val = data << 8;
117 *p++ = val;
118 if (stereo) {
119 if (get_user(data, userPtr++))
120 return -EFAULT;
121 val = data << 8;
122 }
123 *p++ = val;
124 count--;
125 }
126 *frameUsed += used * 4;
127 return stereo? used * 2: used;
128}
129
130
131static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
132 u_char frame[], ssize_t *frameUsed,
133 ssize_t frameLeft)
134{
135 ssize_t count, used;
136 short *p = (short *) &frame[*frameUsed];
137 int val, stereo = dmasound.soft.stereo;
138
139 frameLeft >>= 2;
140 if (stereo)
141 userCount >>= 1;
142 used = count = min_t(unsigned long, userCount, frameLeft);
143 while (count > 0) {
144 u_char data;
145 if (get_user(data, userPtr++))
146 return -EFAULT;
147 val = (data ^ 0x80) << 8;
148 *p++ = val;
149 if (stereo) {
150 if (get_user(data, userPtr++))
151 return -EFAULT;
152 val = (data ^ 0x80) << 8;
153 }
154 *p++ = val;
155 count--;
156 }
157 *frameUsed += used * 4;
158 return stereo? used * 2: used;
159}
160
161
162static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
163 u_char frame[], ssize_t *frameUsed,
164 ssize_t frameLeft)
165{
166 ssize_t count, used;
167 int stereo = dmasound.soft.stereo;
168 short *fp = (short *) &frame[*frameUsed];
169
170 frameLeft >>= 2;
171 userCount >>= (stereo? 2: 1);
172 used = count = min_t(unsigned long, userCount, frameLeft);
173 if (!stereo) {
174 short __user *up = (short __user *) userPtr;
175 while (count > 0) {
176 short data;
177 if (get_user(data, up++))
178 return -EFAULT;
179 *fp++ = data;
180 *fp++ = data;
181 count--;
182 }
183 } else {
184 if (copy_from_user(fp, userPtr, count * 4))
185 return -EFAULT;
186 }
187 *frameUsed += used * 4;
188 return stereo? used * 4: used * 2;
189}
190
191static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
192 u_char frame[], ssize_t *frameUsed,
193 ssize_t frameLeft)
194{
195 ssize_t count, used;
196 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
197 int stereo = dmasound.soft.stereo;
198 short *fp = (short *) &frame[*frameUsed];
199 short __user *up = (short __user *) userPtr;
200
201 frameLeft >>= 2;
202 userCount >>= (stereo? 2: 1);
203 used = count = min_t(unsigned long, userCount, frameLeft);
204 while (count > 0) {
205 short data;
206 if (get_user(data, up++))
207 return -EFAULT;
208 data ^= mask;
209 *fp++ = data;
210 if (stereo) {
211 if (get_user(data, up++))
212 return -EFAULT;
213 data ^= mask;
214 }
215 *fp++ = data;
216 count--;
217 }
218 *frameUsed += used * 4;
219 return stereo? used * 4: used * 2;
220}
221
222
223static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
224 u_char frame[], ssize_t *frameUsed,
225 ssize_t frameLeft)
226{
227 unsigned short *table = (unsigned short *)
228 (dmasound.soft.format == AFMT_MU_LAW
229 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
230 unsigned int data = expand_data;
231 unsigned int *p = (unsigned int *) &frame[*frameUsed];
232 int bal = expand_bal;
233 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
234 int utotal, ftotal;
235 int stereo = dmasound.soft.stereo;
236
237 frameLeft >>= 2;
238 if (stereo)
239 userCount >>= 1;
240 ftotal = frameLeft;
241 utotal = userCount;
242 while (frameLeft) {
243 u_char c;
244 if (bal < 0) {
245 if (userCount == 0)
246 break;
247 if (get_user(c, userPtr++))
248 return -EFAULT;
249 data = table[c];
250 if (stereo) {
251 if (get_user(c, userPtr++))
252 return -EFAULT;
253 data = (data << 16) + table[c];
254 } else
255 data = (data << 16) + data;
256 userCount--;
257 bal += hSpeed;
258 }
259 *p++ = data;
260 frameLeft--;
261 bal -= sSpeed;
262 }
263 expand_bal = bal;
264 expand_data = data;
265 *frameUsed += (ftotal - frameLeft) * 4;
266 utotal -= userCount;
267 return stereo? utotal * 2: utotal;
268}
269
270static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
271 u_char frame[], ssize_t *frameUsed,
272 ssize_t frameLeft)
273{
274 unsigned int *p = (unsigned int *) &frame[*frameUsed];
275 unsigned int data = expand_data;
276 int bal = expand_bal;
277 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
278 int stereo = dmasound.soft.stereo;
279 int utotal, ftotal;
280
281 frameLeft >>= 2;
282 if (stereo)
283 userCount >>= 1;
284 ftotal = frameLeft;
285 utotal = userCount;
286 while (frameLeft) {
287 u_char c;
288 if (bal < 0) {
289 if (userCount == 0)
290 break;
291 if (get_user(c, userPtr++))
292 return -EFAULT;
293 data = c << 8;
294 if (stereo) {
295 if (get_user(c, userPtr++))
296 return -EFAULT;
297 data = (data << 16) + (c << 8);
298 } else
299 data = (data << 16) + data;
300 userCount--;
301 bal += hSpeed;
302 }
303 *p++ = data;
304 frameLeft--;
305 bal -= sSpeed;
306 }
307 expand_bal = bal;
308 expand_data = data;
309 *frameUsed += (ftotal - frameLeft) * 4;
310 utotal -= userCount;
311 return stereo? utotal * 2: utotal;
312}
313
314
315static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
316 u_char frame[], ssize_t *frameUsed,
317 ssize_t frameLeft)
318{
319 unsigned int *p = (unsigned int *) &frame[*frameUsed];
320 unsigned int data = expand_data;
321 int bal = expand_bal;
322 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
323 int stereo = dmasound.soft.stereo;
324 int utotal, ftotal;
325
326 frameLeft >>= 2;
327 if (stereo)
328 userCount >>= 1;
329 ftotal = frameLeft;
330 utotal = userCount;
331 while (frameLeft) {
332 u_char c;
333 if (bal < 0) {
334 if (userCount == 0)
335 break;
336 if (get_user(c, userPtr++))
337 return -EFAULT;
338 data = (c ^ 0x80) << 8;
339 if (stereo) {
340 if (get_user(c, userPtr++))
341 return -EFAULT;
342 data = (data << 16) + ((c ^ 0x80) << 8);
343 } else
344 data = (data << 16) + data;
345 userCount--;
346 bal += hSpeed;
347 }
348 *p++ = data;
349 frameLeft--;
350 bal -= sSpeed;
351 }
352 expand_bal = bal;
353 expand_data = data;
354 *frameUsed += (ftotal - frameLeft) * 4;
355 utotal -= userCount;
356 return stereo? utotal * 2: utotal;
357}
358
359
360static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
361 u_char frame[], ssize_t *frameUsed,
362 ssize_t frameLeft)
363{
364 unsigned int *p = (unsigned int *) &frame[*frameUsed];
365 unsigned int data = expand_data;
366 unsigned short __user *up = (unsigned short __user *) userPtr;
367 int bal = expand_bal;
368 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
369 int stereo = dmasound.soft.stereo;
370 int utotal, ftotal;
371
372 frameLeft >>= 2;
373 userCount >>= (stereo? 2: 1);
374 ftotal = frameLeft;
375 utotal = userCount;
376 while (frameLeft) {
377 unsigned short c;
378 if (bal < 0) {
379 if (userCount == 0)
380 break;
381 if (get_user(data, up++))
382 return -EFAULT;
383 if (stereo) {
384 if (get_user(c, up++))
385 return -EFAULT;
386 data = (data << 16) + c;
387 } else
388 data = (data << 16) + data;
389 userCount--;
390 bal += hSpeed;
391 }
392 *p++ = data;
393 frameLeft--;
394 bal -= sSpeed;
395 }
396 expand_bal = bal;
397 expand_data = data;
398 *frameUsed += (ftotal - frameLeft) * 4;
399 utotal -= userCount;
400 return stereo? utotal * 4: utotal * 2;
401}
402
403
404static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
405 u_char frame[], ssize_t *frameUsed,
406 ssize_t frameLeft)
407{
408 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
409 unsigned int *p = (unsigned int *) &frame[*frameUsed];
410 unsigned int data = expand_data;
411 unsigned short __user *up = (unsigned short __user *) userPtr;
412 int bal = expand_bal;
413 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
414 int stereo = dmasound.soft.stereo;
415 int utotal, ftotal;
416
417 frameLeft >>= 2;
418 userCount >>= (stereo? 2: 1);
419 ftotal = frameLeft;
420 utotal = userCount;
421 while (frameLeft) {
422 unsigned short c;
423 if (bal < 0) {
424 if (userCount == 0)
425 break;
426 if (get_user(data, up++))
427 return -EFAULT;
428 data ^= mask;
429 if (stereo) {
430 if (get_user(c, up++))
431 return -EFAULT;
432 data = (data << 16) + (c ^ mask);
433 } else
434 data = (data << 16) + data;
435 userCount--;
436 bal += hSpeed;
437 }
438 *p++ = data;
439 frameLeft--;
440 bal -= sSpeed;
441 }
442 expand_bal = bal;
443 expand_data = data;
444 *frameUsed += (ftotal - frameLeft) * 4;
445 utotal -= userCount;
446 return stereo? utotal * 4: utotal * 2;
447}
448
449/* data in routines... */
450
451static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
452 u_char frame[], ssize_t *frameUsed,
453 ssize_t frameLeft)
454{
455 ssize_t count, used;
456 short *p = (short *) &frame[*frameUsed];
457 int val, stereo = dmasound.soft.stereo;
458
459 frameLeft >>= 2;
460 if (stereo)
461 userCount >>= 1;
462 used = count = min_t(unsigned long, userCount, frameLeft);
463 while (count > 0) {
464 u_char data;
465
466 val = *p++;
467 val = (val * software_input_volume) >> 7;
468 data = val >> 8;
469 if (put_user(data, (u_char __user *)userPtr++))
470 return -EFAULT;
471 if (stereo) {
472 val = *p;
473 val = (val * software_input_volume) >> 7;
474 data = val >> 8;
475 if (put_user(data, (u_char __user *)userPtr++))
476 return -EFAULT;
477 }
478 p++;
479 count--;
480 }
481 *frameUsed += used * 4;
482 return stereo? used * 2: used;
483}
484
485
486static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
487 u_char frame[], ssize_t *frameUsed,
488 ssize_t frameLeft)
489{
490 ssize_t count, used;
491 short *p = (short *) &frame[*frameUsed];
492 int val, stereo = dmasound.soft.stereo;
493
494 frameLeft >>= 2;
495 if (stereo)
496 userCount >>= 1;
497 used = count = min_t(unsigned long, userCount, frameLeft);
498 while (count > 0) {
499 u_char data;
500
501 val = *p++;
502 val = (val * software_input_volume) >> 7;
503 data = (val >> 8) ^ 0x80;
504 if (put_user(data, (u_char __user *)userPtr++))
505 return -EFAULT;
506 if (stereo) {
507 val = *p;
508 val = (val * software_input_volume) >> 7;
509 data = (val >> 8) ^ 0x80;
510 if (put_user(data, (u_char __user *)userPtr++))
511 return -EFAULT;
512 }
513 p++;
514 count--;
515 }
516 *frameUsed += used * 4;
517 return stereo? used * 2: used;
518}
519
520static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
521 u_char frame[], ssize_t *frameUsed,
522 ssize_t frameLeft)
523{
524 ssize_t count, used;
525 int stereo = dmasound.soft.stereo;
526 short *fp = (short *) &frame[*frameUsed];
527 short __user *up = (short __user *) userPtr;
528
529 frameLeft >>= 2;
530 userCount >>= (stereo? 2: 1);
531 used = count = min_t(unsigned long, userCount, frameLeft);
532 while (count > 0) {
533 short data;
534
535 data = *fp++;
536 data = (data * software_input_volume) >> 7;
537 if (put_user(data, up++))
538 return -EFAULT;
539 if (stereo) {
540 data = *fp;
541 data = (data * software_input_volume) >> 7;
542 if (put_user(data, up++))
543 return -EFAULT;
544 }
545 fp++;
546 count--;
547 }
548 *frameUsed += used * 4;
549 return stereo? used * 4: used * 2;
550}
551
552static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
553 u_char frame[], ssize_t *frameUsed,
554 ssize_t frameLeft)
555{
556 ssize_t count, used;
557 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
558 int stereo = dmasound.soft.stereo;
559 short *fp = (short *) &frame[*frameUsed];
560 short __user *up = (short __user *) userPtr;
561
562 frameLeft >>= 2;
563 userCount >>= (stereo? 2: 1);
564 used = count = min_t(unsigned long, userCount, frameLeft);
565 while (count > 0) {
566 int data;
567
568 data = *fp++;
569 data = (data * software_input_volume) >> 7;
570 data ^= mask;
571 if (put_user(data, up++))
572 return -EFAULT;
573 if (stereo) {
574 data = *fp;
575 data = (data * software_input_volume) >> 7;
576 data ^= mask;
577 if (put_user(data, up++))
578 return -EFAULT;
579 }
580 fp++;
581 count--;
582 }
583 *frameUsed += used * 4;
584 return stereo? used * 4: used * 2;
585}
586
587/* data in routines (reducing speed)... */
588
589static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
590 u_char frame[], ssize_t *frameUsed,
591 ssize_t frameLeft)
592{
593 short *p = (short *) &frame[*frameUsed];
594 int bal = expand_read_bal;
595 int vall,valr, stereo = dmasound.soft.stereo;
596 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
597 int utotal, ftotal;
598
599 frameLeft >>= 2;
600 if (stereo)
601 userCount >>= 1;
602 ftotal = frameLeft;
603 utotal = userCount;
604 while (frameLeft) {
605 u_char data;
606
607 if (bal<0 && userCount == 0)
608 break;
609 vall = *p++;
610 vall = (vall * software_input_volume) >> 7;
611 if (stereo) {
612 valr = *p;
613 valr = (valr * software_input_volume) >> 7;
614 }
615 p++;
616 if (bal < 0) {
617 data = vall >> 8;
618 if (put_user(data, (u_char __user *)userPtr++))
619 return -EFAULT;
620 if (stereo) {
621 data = valr >> 8;
622 if (put_user(data, (u_char __user *)userPtr++))
623 return -EFAULT;
624 }
625 userCount--;
626 bal += hSpeed;
627 }
628 frameLeft--;
629 bal -= sSpeed;
630 }
631 expand_read_bal=bal;
632 *frameUsed += (ftotal - frameLeft) * 4;
633 utotal -= userCount;
634 return stereo? utotal * 2: utotal;
635}
636
637
638static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
639 u_char frame[], ssize_t *frameUsed,
640 ssize_t frameLeft)
641{
642 short *p = (short *) &frame[*frameUsed];
643 int bal = expand_read_bal;
644 int vall,valr, stereo = dmasound.soft.stereo;
645 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
646 int utotal, ftotal;
647
648 frameLeft >>= 2;
649 if (stereo)
650 userCount >>= 1;
651 ftotal = frameLeft;
652 utotal = userCount;
653 while (frameLeft) {
654 u_char data;
655
656 if (bal<0 && userCount == 0)
657 break;
658
659 vall = *p++;
660 vall = (vall * software_input_volume) >> 7;
661 if (stereo) {
662 valr = *p;
663 valr = (valr * software_input_volume) >> 7;
664 }
665 p++;
666 if (bal < 0) {
667 data = (vall >> 8) ^ 0x80;
668 if (put_user(data, (u_char __user *)userPtr++))
669 return -EFAULT;
670 if (stereo) {
671 data = (valr >> 8) ^ 0x80;
672 if (put_user(data, (u_char __user *)userPtr++))
673 return -EFAULT;
674 }
675 userCount--;
676 bal += hSpeed;
677 }
678 frameLeft--;
679 bal -= sSpeed;
680 }
681 expand_read_bal=bal;
682 *frameUsed += (ftotal - frameLeft) * 4;
683 utotal -= userCount;
684 return stereo? utotal * 2: utotal;
685}
686
687static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
688 u_char frame[], ssize_t *frameUsed,
689 ssize_t frameLeft)
690{
691 int bal = expand_read_bal;
692 short *fp = (short *) &frame[*frameUsed];
693 short __user *up = (short __user *) userPtr;
694 int stereo = dmasound.soft.stereo;
695 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
696 int utotal, ftotal;
697
698 frameLeft >>= 2;
699 userCount >>= (stereo? 2: 1);
700 ftotal = frameLeft;
701 utotal = userCount;
702 while (frameLeft) {
703 int datal,datar;
704
705 if (bal<0 && userCount == 0)
706 break;
707
708 datal = *fp++;
709 datal = (datal * software_input_volume) >> 7;
710 if (stereo) {
711 datar = *fp;
712 datar = (datar * software_input_volume) >> 7;
713 }
714 fp++;
715 if (bal < 0) {
716 if (put_user(datal, up++))
717 return -EFAULT;
718 if (stereo) {
719 if (put_user(datar, up++))
720 return -EFAULT;
721 }
722 userCount--;
723 bal += hSpeed;
724 }
725 frameLeft--;
726 bal -= sSpeed;
727 }
728 expand_read_bal=bal;
729 *frameUsed += (ftotal - frameLeft) * 4;
730 utotal -= userCount;
731 return stereo? utotal * 4: utotal * 2;
732}
733
734static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
735 u_char frame[], ssize_t *frameUsed,
736 ssize_t frameLeft)
737{
738 int bal = expand_read_bal;
739 int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
740 short *fp = (short *) &frame[*frameUsed];
741 short __user *up = (short __user *) userPtr;
742 int stereo = dmasound.soft.stereo;
743 int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
744 int utotal, ftotal;
745
746 frameLeft >>= 2;
747 userCount >>= (stereo? 2: 1);
748 ftotal = frameLeft;
749 utotal = userCount;
750 while (frameLeft) {
751 int datal,datar;
752
753 if (bal<0 && userCount == 0)
754 break;
755
756 datal = *fp++;
757 datal = (datal * software_input_volume) >> 7;
758 datal ^= mask;
759 if (stereo) {
760 datar = *fp;
761 datar = (datar * software_input_volume) >> 7;
762 datar ^= mask;
763 }
764 fp++;
765 if (bal < 0) {
766 if (put_user(datal, up++))
767 return -EFAULT;
768 if (stereo) {
769 if (put_user(datar, up++))
770 return -EFAULT;
771 }
772 userCount--;
773 bal += hSpeed;
774 }
775 frameLeft--;
776 bal -= sSpeed;
777 }
778 expand_read_bal=bal;
779 *frameUsed += (ftotal - frameLeft) * 4;
780 utotal -= userCount;
781 return stereo? utotal * 4: utotal * 2;
782}
783
784
785TRANS transAwacsNormal = {
786 .ct_ulaw= pmac_ct_law,
787 .ct_alaw= pmac_ct_law,
788 .ct_s8= pmac_ct_s8,
789 .ct_u8= pmac_ct_u8,
790 .ct_s16be= pmac_ct_s16,
791 .ct_u16be= pmac_ct_u16,
792 .ct_s16le= pmac_ct_s16,
793 .ct_u16le= pmac_ct_u16,
794};
795
796TRANS transAwacsExpand = {
797 .ct_ulaw= pmac_ctx_law,
798 .ct_alaw= pmac_ctx_law,
799 .ct_s8= pmac_ctx_s8,
800 .ct_u8= pmac_ctx_u8,
801 .ct_s16be= pmac_ctx_s16,
802 .ct_u16be= pmac_ctx_u16,
803 .ct_s16le= pmac_ctx_s16,
804 .ct_u16le= pmac_ctx_u16,
805};
806
807TRANS transAwacsNormalRead = {
808 .ct_s8= pmac_ct_s8_read,
809 .ct_u8= pmac_ct_u8_read,
810 .ct_s16be= pmac_ct_s16_read,
811 .ct_u16be= pmac_ct_u16_read,
812 .ct_s16le= pmac_ct_s16_read,
813 .ct_u16le= pmac_ct_u16_read,
814};
815
816TRANS transAwacsExpandRead = {
817 .ct_s8= pmac_ctx_s8_read,
818 .ct_u8= pmac_ctx_u8_read,
819 .ct_s16be= pmac_ctx_s16_read,
820 .ct_u16be= pmac_ctx_u16_read,
821 .ct_s16le= pmac_ctx_s16_read,
822 .ct_u16le= pmac_ctx_u16_read,
823};
824
825/* translation tables */
826/* 16 bit mu-law */
827
828static short dmasound_ulaw2dma16[] = {
829 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
830 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
831 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
832 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
833 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
834 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
835 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
836 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
837 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
838 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
839 -876, -844, -812, -780, -748, -716, -684, -652,
840 -620, -588, -556, -524, -492, -460, -428, -396,
841 -372, -356, -340, -324, -308, -292, -276, -260,
842 -244, -228, -212, -196, -180, -164, -148, -132,
843 -120, -112, -104, -96, -88, -80, -72, -64,
844 -56, -48, -40, -32, -24, -16, -8, 0,
845 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
846 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
847 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
848 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
849 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
850 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
851 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
852 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
853 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
854 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
855 876, 844, 812, 780, 748, 716, 684, 652,
856 620, 588, 556, 524, 492, 460, 428, 396,
857 372, 356, 340, 324, 308, 292, 276, 260,
858 244, 228, 212, 196, 180, 164, 148, 132,
859 120, 112, 104, 96, 88, 80, 72, 64,
860 56, 48, 40, 32, 24, 16, 8, 0,
861};
862
863/* 16 bit A-law */
864
865static short dmasound_alaw2dma16[] = {
866 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
867 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
868 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
869 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
870 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
871 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
872 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
873 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
874 -344, -328, -376, -360, -280, -264, -312, -296,
875 -472, -456, -504, -488, -408, -392, -440, -424,
876 -88, -72, -120, -104, -24, -8, -56, -40,
877 -216, -200, -248, -232, -152, -136, -184, -168,
878 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
879 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
880 -688, -656, -752, -720, -560, -528, -624, -592,
881 -944, -912, -1008, -976, -816, -784, -880, -848,
882 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
883 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
884 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
885 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
886 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
887 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
888 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
889 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
890 344, 328, 376, 360, 280, 264, 312, 296,
891 472, 456, 504, 488, 408, 392, 440, 424,
892 88, 72, 120, 104, 24, 8, 56, 40,
893 216, 200, 248, 232, 152, 136, 184, 168,
894 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
895 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
896 688, 656, 752, 720, 560, 528, 624, 592,
897 944, 912, 1008, 976, 816, 784, 880, 848,
898};