Merge with 2.3.99-pre9.
[linux-2.6/linux-mips.git] / drivers / char / tda8425.c
bloba1dec22ebc5b67a3525d9e5f92ddaf83786a7f8b
1 /*
2 * for the TDA8425 chip (I don't know which cards have this)
3 * WARNING: THIS DRIVER WILL LOAD WITHOUT COMPLAINTS EVEN IF A DIFFERENT
4 * CHIP IS AT ADDRESS 0x82 (it relies on i2c to make sure that there is a
5 * device acknowledging that address)
7 * Copyright (c) 1998 Greg Alexander <galexand@acm.org>
8 * This code is placed under the terms of the GNU General Public License
9 * Code liberally copied from msp3400.c, which is by Gerd Knorr
11 * All of this should work, though it would be nice to eventually support
12 * balance (different left,right values). Also, the chip seems (?) to have
13 * two stereo inputs, so if someone has this card, could they tell me if the
14 * second one can be used for anything (i.e., does it have an external input
15 * that you can't hear even if you set input to composite?)
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/string.h>
22 #include <linux/timer.h>
23 #include <linux/delay.h>
24 #include <linux/errno.h>
25 #include <linux/malloc.h>
26 #include <linux/videodev.h>
27 #include <linux/i2c.h>
28 #include <linux/i2c-algo-bit.h>
30 #include "bttv.h"
31 #include "audiochip.h"
33 /* Addresses to scan */
34 static unsigned short normal_i2c[] = {
35 I2C_TDA8425 >> 1,
36 I2C_CLIENT_END};
37 static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
38 static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
39 static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
40 static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
41 static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
42 static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
43 static struct i2c_client_address_data addr_data = {
44 normal_i2c, normal_i2c_range,
45 probe, probe_range,
46 ignore, ignore_range,
47 force
50 MODULE_PARM(debug,"i");
51 static int debug = 0; /* insmod parameter */
52 #define dprintk if (debug) printk
55 struct tda8425 {
56 int mode; /* set to AUDIO_{OFF,TUNER,RADIO,EXTERN} */
57 int stereo;
58 __u16 left,right;
59 __u16 bass,treble;
62 static struct i2c_driver driver;
63 static struct i2c_client client_template;
66 #define TDA8425_VL 0x00 /* volume left */
67 #define TDA8425_VR 0x01 /* volume right */
68 #define TDA8425_BA 0x02 /* bass */
69 #define TDA8425_TR 0x03 /* treble */
70 #define TDA8425_S1 0x08 /* switch functions */
71 /* values for those registers: */
72 #define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
73 #define TDA8425_S1_ON 0xCE /* audio on (mute off) - "linear stereo" mode */
76 /* ******************************** *
77 * functions for talking to TDA8425 *
78 * ******************************** */
80 static int tda8425_write(struct i2c_client *client, int addr, int val)
82 unsigned char buffer[2];
84 buffer[0] = addr;
85 buffer[1] = val;
86 if (2 != i2c_master_send(client,buffer,2)) {
87 printk(KERN_WARNING "tda8425: I/O error, trying (write %d 0x%x)\n",
88 addr, val);
89 return -1;
91 return 0;
94 static void tda8425_set(struct i2c_client *client)
96 struct tda8425 *tda = client->data;
98 /* mode is ignored today */
99 dprintk(KERN_DEBUG "tda8425_set(%04x,%04x,%04x,%04x)\n",tda->left>>10,tda->right>>10,tda->bass>>12,tda->treble>>12);
100 tda8425_write(client, TDA8425_VL, tda->left>>10 |0xC0);
101 tda8425_write(client, TDA8425_VR, tda->right>>10 |0xC0);
102 tda8425_write(client, TDA8425_BA, tda->bass>>12 |0xF0);
103 tda8425_write(client, TDA8425_TR, tda->treble>>12|0xF0);
106 static void do_tda8425_init(struct i2c_client *client)
108 struct tda8425 *tda = client->data;
110 tda->left=tda->right =61440; /* 0dB */
111 tda->bass=tda->treble=24576; /* 0dB */
112 tda->mode=AUDIO_OFF;
113 tda->stereo=1;
114 /* left=right=0x27<<10, bass=treble=0x07<<12 */
115 tda8425_write(client, TDA8425_S1, TDA8425_S1_OFF); /* mute */
116 tda8425_set(client);
119 static void tda8425_audio(struct i2c_client *client, int mode)
121 struct tda8425 *tda = client->data;
123 /* valid for AUDIO_TUNER, RADIO, EXTERN, OFF */
124 dprintk(KERN_DEBUG "tda8425_audio:%d (T,R,E,I,O)\n",mode);
125 tda->mode=mode;
126 tda8425_write(client, TDA8425_S1,
127 (mode==AUDIO_OFF)?TDA8425_S1_OFF:TDA8425_S1_ON);
128 /* this is the function we'll need to change if it turns out the
129 * input-selecting capabilities should be used. */
133 /* *********************** *
134 * i2c interface functions *
135 * *********************** */
137 static int tda8425_attach(struct i2c_adapter *adap, int addr,
138 unsigned short flags, int kind)
140 struct tda8425 *tda;
141 struct i2c_client *client;
143 client = kmalloc(sizeof *client,GFP_KERNEL);
144 if (!client)
145 return -ENOMEM;
146 memcpy(client,&client_template,sizeof(struct i2c_client));
147 client->adapter = adap;
148 client->addr = addr;
150 client->data = tda = kmalloc(sizeof *tda,GFP_KERNEL);
151 if (!tda)
152 return -ENOMEM;
153 memset(tda,0,sizeof *tda);
154 do_tda8425_init(client);
155 MOD_INC_USE_COUNT;
156 strcpy(client->name,"TDA8425");
157 printk(KERN_INFO "tda8425: init\n");
159 i2c_attach_client(client);
160 return 0;
163 static int tda8425_probe(struct i2c_adapter *adap)
165 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
166 return i2c_probe(adap, &addr_data, tda8425_attach);
167 return 0;
171 static int tda8425_detach(struct i2c_client *client)
173 struct tda8425 *tda = client->data;
175 do_tda8425_init(client);
176 i2c_detach_client(client);
178 kfree(tda);
179 kfree(client);
180 MOD_DEC_USE_COUNT;
181 return 0;
184 static int tda8425_command(struct i2c_client *client,
185 unsigned int cmd, void *arg)
187 struct tda8425 *tda = client->data;
188 __u16 *sarg = arg;
190 switch (cmd) {
191 case AUDC_SET_RADIO:
192 tda8425_audio(client,AUDIO_RADIO);
193 break;
194 case AUDC_SET_INPUT:
195 tda8425_audio(client,*sarg);
196 break;
198 /* --- v4l ioctls --- */
199 /* take care: bttv does userspace copying, we'll get a
200 kernel pointer here... */
201 case VIDIOCGAUDIO:
203 struct video_audio *va = arg;
205 va->flags |= VIDEO_AUDIO_VOLUME |
206 VIDEO_AUDIO_BASS |
207 VIDEO_AUDIO_TREBLE;
208 va->volume=MAX(tda->left,tda->right);
209 va->balance=(32768*MIN(tda->left,tda->right))/
210 (va->volume ? va->volume : 1);
211 va->balance=(tda->left<tda->right)?
212 (65535-va->balance) : va->balance;
213 va->bass = tda->bass;
214 va->treble = tda->treble;
215 break;
217 case VIDIOCSAUDIO:
219 struct video_audio *va = arg;
221 tda->left = (MIN(65536 - va->balance,32768) *
222 va->volume) / 32768;
223 tda->right = (MIN(va->balance,32768) *
224 va->volume) / 32768;
225 tda->bass = va->bass;
226 tda->treble = va->treble;
227 tda8425_set(client);
228 break;
231 #if 0
232 /* --- old, obsolete interface --- */
233 case AUDC_GET_VOLUME_LEFT:
234 *sarg = tda->left;
235 break;
236 case AUDC_GET_VOLUME_RIGHT:
237 *sarg = tda->right;
238 break;
239 case AUDC_SET_VOLUME_LEFT:
240 tda->left = *sarg;
241 tda8425_set(client);
242 break;
243 case AUDC_SET_VOLUME_RIGHT:
244 tda->right = *sarg;
245 tda8425_set(client);
246 break;
248 case AUDC_GET_BASS:
249 *sarg = tda->bass;
250 break;
251 case AUDC_SET_BASS:
252 tda->bass = *sarg;
253 tda8425_set(client);
254 break;
256 case AUDC_GET_TREBLE:
257 *sarg = tda->treble;
258 break;
259 case AUDC_SET_TREBLE:
260 tda->treble = *sarg;
261 tda8425_set(client);
262 break;
264 case AUDC_GET_STEREO:
265 *sarg = tda->stereo?VIDEO_SOUND_STEREO:VIDEO_SOUND_MONO;
266 break;
267 case AUDC_SET_STEREO:
268 tda->stereo=(*sarg==VIDEO_SOUND_MONO)?0:1;
269 /* TODO: make this write to the TDA9850? */
270 break;
272 /* case AUDC_SWITCH_MUTE: someday, maybe -- not a lot of point to
273 case AUDC_NEWCHANNEL: it and it would require preserving state
274 case AUDC_GET_DC: huh?? (not used by bttv.c)
276 #endif
277 default:
278 /* nothing */
280 return 0;
284 static struct i2c_driver driver = {
285 "i2c tda8424 driver",
286 I2C_DRIVERID_TDA8425,
287 I2C_DF_NOTIFY,
288 tda8425_probe,
289 tda8425_detach,
290 tda8425_command,
293 static struct i2c_client client_template =
295 "(unset)", /* name */
299 NULL,
300 &driver
303 #ifdef MODULE
304 int init_module(void)
305 #else
306 int tda8425_init(void)
307 #endif
309 i2c_add_driver(&driver);
310 return 0;
313 #ifdef MODULE
314 void cleanup_module(void)
316 i2c_del_driver(&driver);
318 #endif
321 * Local variables:
322 * c-basic-offset: 8
323 * End: