Portability cleanup as required by Linus.
[linux-2.6/linux-mips.git] / drivers / char / tea6420.c
blob231ed9e4e0fd529f792b9f7b6d4334eab0f6fbdc
1 /*
2 * for the TEA6420 chip (only found on 3DFX (STB) TV/FM cards to the best
3 * of my knowledge)
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
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/sched.h>
17 #include <linux/string.h>
18 #include <linux/timer.h>
19 #include <linux/delay.h>
20 #include <linux/errno.h>
21 #include <linux/malloc.h>
22 #include <linux/videodev.h>
23 #include <linux/i2c.h>
24 #include <linux/i2c-algo-bit.h>
26 #include "bttv.h"
27 #include "audiochip.h"
30 /* Addresses to scan */
31 #define I2C_TEA6420 0x98
32 static unsigned short normal_i2c[] = {
33 I2C_TEA6420 >> 1,
34 I2C_CLIENT_END};
35 static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
36 static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
37 static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
38 static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
39 static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
40 static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
41 static struct i2c_client_address_data addr_data = {
42 normal_i2c, normal_i2c_range,
43 probe, probe_range,
44 ignore, ignore_range,
45 force
49 MODULE_PARM(debug,"i");
50 static int debug = 0; /* insmod parameter */
52 #define dprintk if (debug) printk
55 struct tea6420 {
56 int mode; /* set to AUDIO_{OFF,TUNER,RADIO,EXTERN} */
57 int stereo;
60 static struct i2c_driver driver;
61 static struct i2c_client client_template;
63 #define TEA6420_S_SA 0x00 /* stereo A input */
64 #define TEA6420_S_SB 0x01 /* stereo B */
65 #define TEA6420_S_SC 0x02 /* stereo C */
66 #define TEA6420_S_SD 0x03 /* stereo D */
67 #define TEA6420_S_SE 0x04 /* stereo E */
68 #define TEA6420_S_GMU 0x05 /* general mute */
71 /* ******************************** *
72 * functions for talking to TEA6420 *
73 * ******************************** */
75 static int tea6420_write(struct i2c_client *client, int val)
77 unsigned char buffer[2];
78 int result;
80 /* buffer[0] = addr; */
81 buffer[0] = val;
82 result = i2c_master_send(client,buffer,1);
83 if (1 != result) {
84 printk(KERN_WARNING "tea6420: I/O error, trying (write
85 0x%x) result = %d\n", val, result);
86 return -1;
88 return 0;
92 static void do_tea6420_init(struct i2c_client *client)
94 struct tea6420 *tea = client->data;
96 tea->mode=AUDIO_OFF;
97 tea->stereo=1;
98 tea6420_write(client, TEA6420_S_GMU); /* mute */
101 static void tea6420_audio(struct i2c_client *client, int mode)
103 struct tea6420 *tea = client->data;
105 /* valid for AUDIO_TUNER, RADIO, EXTERN, OFF */
106 dprintk(KERN_DEBUG "tea6420_audio:%d (T,R,E,I,O)\n",mode);
107 tea->mode=mode;
108 if (mode==AUDIO_OFF) { /* just mute it */
109 tea6420_write(client, TEA6420_S_GMU);
110 return;
112 switch(mode) {
113 case AUDIO_TUNER:
114 tea6420_write(client, TEA6420_S_SA);
115 break;
116 case AUDIO_RADIO:
117 tea6420_write(client, TEA6420_S_SB);
118 break;
119 case AUDIO_EXTERN:
120 tea6420_write(client, TEA6420_S_SC);
121 break;
126 /* *********************** *
127 * i2c interface functions *
128 * *********************** */
130 static int tea6420_attach(struct i2c_adapter *adap, int addr,
131 unsigned short flags, int kind)
133 struct tea6420 *tea;
134 struct i2c_client *client;
136 client = kmalloc(sizeof *client,GFP_KERNEL);
137 if (!client)
138 return -ENOMEM;
139 memcpy(client,&client_template,sizeof(struct i2c_client));
140 client->adapter = adap;
141 client->addr = addr;
143 client->data = tea = kmalloc(sizeof *tea,GFP_KERNEL);
144 if (!tea)
145 return -ENOMEM;
146 memset(tea,0,sizeof *tea);
147 do_tea6420_init(client);
149 MOD_INC_USE_COUNT;
150 strcpy(client->name,"TEA6420");
151 printk(KERN_INFO "tea6420: initialized\n");
153 i2c_attach_client(client);
154 return 0;
157 static int tea6420_probe(struct i2c_adapter *adap)
159 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
160 return i2c_probe(adap, &addr_data, tea6420_attach);
161 return 0;
164 static int tea6420_detach(struct i2c_client *client)
166 struct tea6420 *tea = client->data;
168 do_tea6420_init(client);
169 i2c_detach_client(client);
171 kfree(tea);
172 kfree(client);
173 MOD_DEC_USE_COUNT;
174 return 0;
177 static int
178 tea6420_command(struct i2c_client *client, unsigned int cmd, void *arg)
180 __u16 *sarg = arg;
182 switch (cmd) {
183 case AUDC_SET_RADIO:
184 tea6420_audio(client,AUDIO_RADIO);
185 break;
186 case AUDC_SET_INPUT:
187 tea6420_audio(client,*sarg);
188 break;
190 /* --- v4l ioctls --- */
191 /* take care: bttv does userspace copying, we'll get a
192 kernel pointer here... */
193 case VIDIOCGAUDIO:
195 struct video_audio *va = arg;
197 va->flags |= VIDEO_AUDIO_VOLUME |
198 VIDEO_AUDIO_BASS |
199 VIDEO_AUDIO_TREBLE;
200 /* va->volume=MAX(tea->left,tea->right);
201 va->balance=(32768*MIN(tea->left,tea->right))/
202 (va->volume ? va->volume : 1);
203 va->balance=(tea->left<tea->right)?
204 (65535-va->balance) : va->balance;
205 va->bass = tea->bass;
206 va->treble = tea->treble;
207 */ break;
209 case VIDIOCSAUDIO:
212 /* tea->left = (MIN(65536 - va->balance,32768) *
213 va->volume) / 32768;
214 tea->right = (MIN(va->balance,32768) *
215 va->volume) / 32768;
216 tea->bass = va->bass;
217 tea->treble = va->treble;
218 tea6420_set(client);
219 */ break;
222 default:
223 /* nothing */
225 return 0;
228 static struct i2c_driver driver = {
229 "i2c tea6420 driver",
230 I2C_DRIVERID_TEA6420,
231 I2C_DF_NOTIFY,
232 tea6420_probe,
233 tea6420_detach,
234 tea6420_command,
237 static struct i2c_client client_template =
239 "(unset)", /* name */
243 NULL,
244 &driver
247 #ifdef MODULE
248 int init_module(void)
249 #else
250 int tea6420_init(void)
251 #endif
253 i2c_add_driver(&driver);
254 return 0;
257 #ifdef MODULE
258 void cleanup_module(void)
260 i2c_del_driver(&driver);
262 #endif
265 * Local variables:
266 * c-basic-offset: 8
267 * End: