2 * for the TEA6420 chip (only found on 3DFX (STB) TV/FM cards to the best
4 * Copyright (C) 2000 Dave Stuart <justdave@ynn.com>
5 * This code is placed under the terms of the GNU General Public License
6 * Code liberally copied from tea6300 by . . .
8 * Copyright (c) 1998 Greg Alexander <galexand@acm.org>
9 * This code is placed under the terms of the GNU General Public License
10 * Code liberally copied from msp3400.c, which is by Gerd Knorr
13 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/14/2000
14 * - resource allocation fixes in tea6300_attach
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/string.h>
21 #include <linux/timer.h>
22 #include <linux/delay.h>
23 #include <linux/errno.h>
24 #include <linux/malloc.h>
25 #include <linux/videodev.h>
26 #include <linux/i2c.h>
27 #include <linux/i2c-algo-bit.h>
30 #include "audiochip.h"
33 /* Addresses to scan */
34 #define I2C_TEA6420 0x98
35 static unsigned short normal_i2c
[] = {
38 static unsigned short normal_i2c_range
[] = {I2C_CLIENT_END
};
39 static unsigned short probe
[2] = { I2C_CLIENT_END
, I2C_CLIENT_END
};
40 static unsigned short probe_range
[2] = { I2C_CLIENT_END
, I2C_CLIENT_END
};
41 static unsigned short ignore
[2] = { I2C_CLIENT_END
, I2C_CLIENT_END
};
42 static unsigned short ignore_range
[2] = { I2C_CLIENT_END
, I2C_CLIENT_END
};
43 static unsigned short force
[2] = { I2C_CLIENT_END
, I2C_CLIENT_END
};
44 static struct i2c_client_address_data addr_data
= {
45 normal_i2c
, normal_i2c_range
,
52 MODULE_PARM(debug
,"i");
53 static int debug
= 0; /* insmod parameter */
55 #define dprintk if (debug) printk
59 int mode
; /* set to AUDIO_{OFF,TUNER,RADIO,EXTERN} */
63 static struct i2c_driver driver
;
64 static struct i2c_client client_template
;
66 #define TEA6420_S_SA 0x00 /* stereo A input */
67 #define TEA6420_S_SB 0x01 /* stereo B */
68 #define TEA6420_S_SC 0x02 /* stereo C */
69 #define TEA6420_S_SD 0x03 /* stereo D */
70 #define TEA6420_S_SE 0x04 /* stereo E */
71 #define TEA6420_S_GMU 0x05 /* general mute */
74 /* ******************************** *
75 * functions for talking to TEA6420 *
76 * ******************************** */
78 static int tea6420_write(struct i2c_client
*client
, int val
)
80 unsigned char buffer
[2];
83 /* buffer[0] = addr; */
85 result
= i2c_master_send(client
,buffer
,1);
87 printk(KERN_WARNING
"tea6420: I/O error, trying (write
88 0x%x) result = %d\n", val
, result
);
95 static void do_tea6420_init(struct i2c_client
*client
)
97 struct tea6420
*tea
= client
->data
;
101 tea6420_write(client
, TEA6420_S_GMU
); /* mute */
104 static void tea6420_audio(struct i2c_client
*client
, int mode
)
106 struct tea6420
*tea
= client
->data
;
108 /* valid for AUDIO_TUNER, RADIO, EXTERN, OFF */
109 dprintk(KERN_DEBUG
"tea6420_audio:%d (T,R,E,I,O)\n",mode
);
111 if (mode
==AUDIO_OFF
) { /* just mute it */
112 tea6420_write(client
, TEA6420_S_GMU
);
117 tea6420_write(client
, TEA6420_S_SA
);
120 tea6420_write(client
, TEA6420_S_SB
);
123 tea6420_write(client
, TEA6420_S_SC
);
129 /* *********************** *
130 * i2c interface functions *
131 * *********************** */
133 static int tea6420_attach(struct i2c_adapter
*adap
, int addr
,
134 unsigned short flags
, int kind
)
137 struct i2c_client
*client
;
139 client
= kmalloc(sizeof *client
,GFP_KERNEL
);
142 memcpy(client
,&client_template
,sizeof(struct i2c_client
));
143 client
->adapter
= adap
;
146 client
->data
= tea
= kmalloc(sizeof *tea
,GFP_KERNEL
);
151 memset(tea
,0,sizeof *tea
);
152 do_tea6420_init(client
);
155 strcpy(client
->name
,"TEA6420");
156 printk(KERN_INFO
"tea6420: initialized\n");
158 i2c_attach_client(client
);
162 static int tea6420_probe(struct i2c_adapter
*adap
)
164 if (adap
->id
== (I2C_ALGO_BIT
| I2C_HW_B_BT848
))
165 return i2c_probe(adap
, &addr_data
, tea6420_attach
);
169 static int tea6420_detach(struct i2c_client
*client
)
171 struct tea6420
*tea
= client
->data
;
173 do_tea6420_init(client
);
174 i2c_detach_client(client
);
183 tea6420_command(struct i2c_client
*client
, unsigned int cmd
, void *arg
)
189 tea6420_audio(client
,AUDIO_RADIO
);
192 tea6420_audio(client
,*sarg
);
195 /* --- v4l ioctls --- */
196 /* take care: bttv does userspace copying, we'll get a
197 kernel pointer here... */
200 struct video_audio
*va
= arg
;
202 va
->flags
|= VIDEO_AUDIO_VOLUME
|
205 /* va->volume=MAX(tea->left,tea->right);
206 va->balance=(32768*MIN(tea->left,tea->right))/
207 (va->volume ? va->volume : 1);
208 va->balance=(tea->left<tea->right)?
209 (65535-va->balance) : va->balance;
210 va->bass = tea->bass;
211 va->treble = tea->treble;
217 /* tea->left = (MIN(65536 - va->balance,32768) *
219 tea->right = (MIN(va->balance,32768) *
221 tea->bass = va->bass;
222 tea->treble = va->treble;
233 static struct i2c_driver driver
= {
234 "i2c tea6420 driver",
235 I2C_DRIVERID_TEA6420
,
242 static struct i2c_client client_template
=
244 "(unset)", /* name */
253 int init_module(void)
255 int tea6420_init(void)
258 i2c_add_driver(&driver
);
263 void cleanup_module(void)
265 i2c_del_driver(&driver
);