This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / video / tveeprom.c
1 /*
2  * tveeprom - eeprom decoder for tvcard configuration eeproms
3  *
4  * Data and decoding routines shamelessly borrowed from bttv-cards.c
5  * eeprom access routine shamelessly borrowed from bttv-if.c
6  * which are:
7
8     Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
9                            & Marcus Metzler (mocm@thp.uni-koeln.de)
10     (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11
12  * Adjustments to fit a more general model and all bugs:
13
14         Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29  */
30
31
32 #include <linux/module.h>
33 #include <linux/errno.h>
34 #include <linux/kernel.h>
35 #include <linux/init.h>
36 #include <linux/types.h>
37 #include <linux/i2c.h>
38
39 #include <media/tuner.h>
40 #include <media/tveeprom.h>
41
42 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
43 MODULE_AUTHOR("John Klar");
44 MODULE_LICENSE("GPL");
45
46 static int debug = 0;
47 module_param(debug, int, 0644);
48 MODULE_PARM_DESC(debug, "Debug level (0-2)");
49
50 #define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
51
52 #define dprintk(num, args...) \
53         do { \
54                 if (debug >= num) \
55                         printk(KERN_INFO "tveeprom: " args); \
56         } while (0)
57
58 #define TVEEPROM_KERN_ERR(args...) printk(KERN_ERR "tveeprom: " args);
59 #define TVEEPROM_KERN_INFO(args...) printk(KERN_INFO "tveeprom: " args);
60
61 /* ----------------------------------------------------------------------- */
62 /* some hauppauge specific stuff                                           */
63
64 static struct HAUPPAUGE_TUNER_FMT
65 {
66         int     id;
67         char *name;
68 }
69 hauppauge_tuner_fmt[] =
70 {
71         { 0x00000000, "unknown1" },
72         { 0x00000000, "unknown2" },
73         { 0x00000007, "PAL(B/G)" },
74         { 0x00001000, "NTSC(M)" },
75         { 0x00000010, "PAL(I)" },
76         { 0x00400000, "SECAM(L/L�)" },
77         { 0x00000e00, "PAL(D/K)" },
78         { 0x03000000, "ATSC Digital" },
79 };
80
81 /* This is the full list of possible tuners. Many thanks to Hauppauge for
82    supplying this information. Note that many tuners where only used for
83    testing and never made it to the outside world. So you will only see
84    a subset in actual produced cards. */
85 static struct HAUPPAUGE_TUNER
86 {
87         int  id;
88         char *name;
89 }
90 hauppauge_tuner[] =
91 {
92         /* 0-9 */
93         { TUNER_ABSENT,        "None" },
94         { TUNER_ABSENT,        "External" },
95         { TUNER_ABSENT,        "Unspecified" },
96         { TUNER_PHILIPS_PAL,   "Philips FI1216" },
97         { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
98         { TUNER_PHILIPS_NTSC,  "Philips FI1236" },
99         { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
100         { TUNER_PHILIPS_PAL_DK,"Philips FI1256" },
101         { TUNER_PHILIPS_PAL,   "Philips FI1216 MK2" },
102         { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
103         /* 10-19 */
104         { TUNER_PHILIPS_NTSC,  "Philips FI1236 MK2" },
105         { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
106         { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" },
107         { TUNER_TEMIC_NTSC,    "Temic 4032FY5" },
108         { TUNER_TEMIC_PAL,     "Temic 4002FH5" },
109         { TUNER_TEMIC_PAL_I,   "Temic 4062FY5" },
110         { TUNER_PHILIPS_PAL,   "Philips FR1216 MK2" },
111         { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
112         { TUNER_PHILIPS_NTSC,  "Philips FR1236 MK2" },
113         { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
114         /* 20-29 */
115         { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" },
116         { TUNER_PHILIPS_PAL,   "Philips FM1216" },
117         { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
118         { TUNER_PHILIPS_NTSC,  "Philips FM1236" },
119         { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
120         { TUNER_PHILIPS_PAL_DK,"Philips FM1256" },
121         { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
122         { TUNER_ABSENT,        "Samsung TCPN9082D" },
123         { TUNER_ABSENT,        "Samsung TCPM9092P" },
124         { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
125         /* 30-39 */
126         { TUNER_ABSENT,        "Samsung TCPN9085D" },
127         { TUNER_ABSENT,        "Samsung TCPB9085P" },
128         { TUNER_ABSENT,        "Samsung TCPL9091P" },
129         { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
130         { TUNER_PHILIPS_FQ1216ME,   "Philips FQ1216 ME" },
131         { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
132         { TUNER_PHILIPS_NTSC,        "Philips TD1536" },
133         { TUNER_PHILIPS_NTSC,        "Philips TD1536D" },
134         { TUNER_PHILIPS_NTSC,  "Philips FMR1236" }, /* mono radio */
135         { TUNER_ABSENT,        "Philips FI1256MP" },
136         /* 40-49 */
137         { TUNER_ABSENT,        "Samsung TCPQ9091P" },
138         { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
139         { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
140         { TUNER_TEMIC_4046FM5,     "Temic 4046FM5" },
141         { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
142         { TUNER_ABSENT,        "Philips TD1536D FH 44"},
143         { TUNER_LG_NTSC_FM,    "LG TP18NSR01F"},
144         { TUNER_LG_PAL_FM,     "LG TP18PSB01D"},
145         { TUNER_LG_PAL,        "LG TP18PSB11D"},
146         { TUNER_LG_PAL_I_FM,   "LG TAPC-I001D"},
147         /* 50-59 */
148         { TUNER_LG_PAL_I,      "LG TAPC-I701D"},
149         { TUNER_ABSENT,        "Temic 4042FI5"},
150         { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
151         { TUNER_ABSENT,        "LG TPI8NSR11F"},
152         { TUNER_ABSENT,        "Microtune 4049 FM5 Alt I2C"},
153         { TUNER_ABSENT,        "Philips FQ1216ME MK3"},
154         { TUNER_ABSENT,        "Philips FI1236 MK3"},
155         { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
156         { TUNER_ABSENT,        "Philips FM1236 MK3"},
157         { TUNER_ABSENT,        "Philips FM1216MP MK3"},
158         /* 60-69 */
159         { TUNER_ABSENT,        "LG S001D MK3"},
160         { TUNER_ABSENT,        "LG M001D MK3"},
161         { TUNER_ABSENT,        "LG S701D MK3"},
162         { TUNER_ABSENT,        "LG M701D MK3"},
163         { TUNER_ABSENT,        "Temic 4146FM5"},
164         { TUNER_ABSENT,        "Temic 4136FY5"},
165         { TUNER_ABSENT,        "Temic 4106FH5"},
166         { TUNER_ABSENT,        "Philips FQ1216LMP MK3"},
167         { TUNER_LG_NTSC_TAPE,  "LG TAPE H001F MK3"},
168         { TUNER_ABSENT,        "LG TAPE H701F MK3"},
169         /* 70-79 */
170         { TUNER_ABSENT,        "LG TALN H200T"},
171         { TUNER_ABSENT,        "LG TALN H250T"},
172         { TUNER_ABSENT,        "LG TALN M200T"},
173         { TUNER_ABSENT,        "LG TALN Z200T"},
174         { TUNER_ABSENT,        "LG TALN S200T"},
175         { TUNER_ABSENT,        "Thompson DTT7595"},
176         { TUNER_ABSENT,        "Thompson DTT7592"},
177         { TUNER_ABSENT,        "Silicon TDA8275C1 8290"},
178         { TUNER_ABSENT,        "Silicon TDA8275C1 8290 FM"},
179         { TUNER_ABSENT,        "Thompson DTT757"},
180         /* 80-89 */
181         { TUNER_ABSENT,        "Philips FQ1216LME MK3"},
182         { TUNER_ABSENT,        "LG TAPC G701D"},
183         { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
184         { TUNER_ABSENT,        "TCL 2002MB 3"},
185         { TUNER_ABSENT,        "TCL 2002MI 3"},
186         { TUNER_TCL_2002N,     "TCL 2002N 6A"},
187         { TUNER_ABSENT,        "Philips FQ1236 MK3"},
188         { TUNER_ABSENT,        "Samsung TCPN 2121P30A"},
189         { TUNER_ABSENT,        "Samsung TCPE 4121P30A"},
190         { TUNER_ABSENT,        "TCL MFPE05 2"},
191         /* 90-99 */
192         { TUNER_ABSENT,        "LG TALN H202T"},
193         { TUNER_ABSENT,        "Philips FQ1216AME MK4"},
194         { TUNER_ABSENT,        "Philips FQ1236A MK4"},
195         { TUNER_ABSENT,        "Philips FQ1286A MK4"},
196         { TUNER_ABSENT,        "Philips FQ1216ME MK5"},
197         { TUNER_ABSENT,        "Philips FQ1236 MK5"},
198 };
199
200 static char *sndtype[] = {
201         "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", "MSP3410D",
202         "MSP3415", "MSP3430", "MSP3438", "CS5331", "MSP3435", "MSP3440",
203         "MSP3445", "MSP3411", "MSP3416", "MSP3425",
204
205         "Type 0x10","Type 0x11","Type 0x12","Type 0x13",
206         "Type 0x14","Type 0x15","Type 0x16","Type 0x17",
207         "Type 0x18","MSP4418","Type 0x1a","MSP4448",
208         "Type 0x1c","Type 0x1d","Type 0x1e","Type 0x1f",
209 };
210
211 static int hasRadioTuner(int tunerType)
212 {
213         switch (tunerType) {
214                 case 18: //PNPEnv_TUNER_FR1236_MK2:
215                 case 23: //PNPEnv_TUNER_FM1236:
216                 case 38: //PNPEnv_TUNER_FMR1236:
217                 case 16: //PNPEnv_TUNER_FR1216_MK2:
218                 case 19: //PNPEnv_TUNER_FR1246_MK2:
219                 case 21: //PNPEnv_TUNER_FM1216:
220                 case 24: //PNPEnv_TUNER_FM1246:
221                 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
222                 case 22: //PNPEnv_TUNER_FM1216MF:
223                 case 20: //PNPEnv_TUNER_FR1256_MK2:
224                 case 25: //PNPEnv_TUNER_FM1256:
225                 case 33: //PNPEnv_TUNER_4039FR5:
226                 case 42: //PNPEnv_TUNER_4009FR5:
227                 case 52: //PNPEnv_TUNER_4049FM5:
228                 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
229                 case 44: //PNPEnv_TUNER_4009FN5:
230                 case 31: //PNPEnv_TUNER_TCPB9085P:
231                 case 30: //PNPEnv_TUNER_TCPN9085D:
232                 case 46: //PNPEnv_TUNER_TP18NSR01F:
233                 case 47: //PNPEnv_TUNER_TP18PSB01D:
234                 case 49: //PNPEnv_TUNER_TAPC_I001D:
235                 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
236                 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
237                 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
238                 case 58: //PNPEnv_TUNER_FM1236_MK3:
239                 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
240                 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
241                 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
242                 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
243                     return 1;
244         }
245         return 0;
246 }
247
248 void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data)
249 {
250         /* ----------------------------------------------
251         ** The hauppauge eeprom format is tagged
252         **
253         ** if packet[0] == 0x84, then packet[0..1] == length
254         ** else length = packet[0] & 3f;
255         ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
256         **
257         ** In our (ivtv) case we're interested in the following:
258         ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuners)
259         ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_fmts)
260         ** radio:      tag [00].{last} or [0e].00  (bitmask.  bit2=FM)
261         ** audio proc: tag [02].01 or [05].00 (lower nibble indexes lut?)
262
263         ** Fun info:
264         ** model:      tag [00].07-08 or [06].00-01
265         ** revision:   tag [00].09-0b or [06].04-06
266         ** serial#:    tag [01].05-07 or [04].04-06
267
268         ** # of inputs/outputs ???
269         */
270
271         int i, j, len, done, tag, tuner = 0, t_format = 0;
272         char *t_name = NULL, *t_fmt_name = NULL;
273
274         dprintk(1, "%s\n",__FUNCTION__);
275         tvee->revision = done = len = 0;
276         for (i = 0; !done && i < 256; i += len) {
277                 dprintk(2, "processing pos = %02x (%02x, %02x)\n",
278                         i, eeprom_data[i], eeprom_data[i + 1]);
279
280                 if (eeprom_data[i] == 0x84) {
281                         len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
282                         i+=3;
283                 } else if ((eeprom_data[i] & 0xf0) == 0x70) {
284                         if ((eeprom_data[i] & 0x08)) {
285                                 /* verify checksum! */
286                                 done = 1;
287                                 break;
288                         }
289                         len = eeprom_data[i] & 0x07;
290                         ++i;
291                 } else {
292                         TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. "
293                                    "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
294                         return;
295                 }
296
297                 dprintk(1, "%3d [%02x] ", len, eeprom_data[i]);
298                 for(j = 1; j < len; j++) {
299                         dprintk(1, "%02x ", eeprom_data[i + j]);
300                 }
301                 dprintk(1, "\n");
302
303                 /* process by tag */
304                 tag = eeprom_data[i];
305                 switch (tag) {
306                 case 0x00:
307                         tuner = eeprom_data[i+6];
308                         t_format = eeprom_data[i+5];
309                         tvee->has_radio = eeprom_data[i+len-1];
310                         tvee->model =
311                                 eeprom_data[i+8] +
312                                 (eeprom_data[i+9] << 8);
313                         tvee->revision = eeprom_data[i+10] +
314                                 (eeprom_data[i+11] << 8) +
315                                 (eeprom_data[i+12] << 16);
316                         break;
317                 case 0x01:
318                         tvee->serial_number =
319                                 eeprom_data[i+6] +
320                                 (eeprom_data[i+7] << 8) +
321                                 (eeprom_data[i+8] << 16);
322                         break;
323                 case 0x02:
324                         tvee->audio_processor = eeprom_data[i+2] & 0x0f;
325                         break;
326                 case 0x04:
327                         tvee->serial_number =
328                                 eeprom_data[i+5] +
329                                 (eeprom_data[i+6] << 8) +
330                                 (eeprom_data[i+7] << 16);
331                         break;
332                 case 0x05:
333                         tvee->audio_processor = eeprom_data[i+1] & 0x0f;
334                         break;
335                 case 0x06:
336                         tvee->model =
337                                 eeprom_data[i+1] +
338                                 (eeprom_data[i+2] << 8);
339                         tvee->revision = eeprom_data[i+5] +
340                                 (eeprom_data[i+6] << 8) +
341                                 (eeprom_data[i+7] << 16);
342                         break;
343                 case 0x0a:
344                         tuner = eeprom_data[i+2];
345                         t_format = eeprom_data[i+1];
346                         break;
347                 case 0x0e:
348                         tvee->has_radio = eeprom_data[i+1];
349                         break;
350                 default:
351                         dprintk(1, "Not sure what to do with tag [%02x]\n", tag);
352                         /* dump the rest of the packet? */
353                 }
354
355         }
356
357         if (!done) {
358                 TVEEPROM_KERN_ERR("Ran out of data!\n");
359                 return;
360         }
361
362         if (tvee->revision != 0) {
363                 tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
364                 tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
365                 tvee->rev_str[2] = 32 + ((tvee->revision >>  6) & 0x3f);
366                 tvee->rev_str[3] = 32 + ( tvee->revision        & 0x3f);
367                 tvee->rev_str[4] = 0;
368         }
369
370         if (hasRadioTuner(tuner) && !tvee->has_radio) {
371             TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n");
372             TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n");
373             tvee->has_radio = 1;
374         }
375
376         if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
377                 tvee->tuner_type = hauppauge_tuner[tuner].id;
378                 t_name = hauppauge_tuner[tuner].name;
379         } else {
380                 t_name = "<unknown>";
381         }
382
383         tvee->tuner_formats = 0;
384         t_fmt_name = "<none>";
385         for (i = 0; i < 8; i++) {
386                 if (t_format & (1<<i)) {
387                         tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
388                         /* yuck */
389                         t_fmt_name = hauppauge_tuner_fmt[i].name;
390                 }
391         }
392
393 #if 0
394         if (t_format < sizeof(hauppauge_tuner_fmt)/sizeof(struct HAUPPAUGE_TUNER_FMT)) {
395                 tvee->tuner_formats = hauppauge_tuner_fmt[t_format].id;
396                 t_fmt_name = hauppauge_tuner_fmt[t_format].name;
397         } else {
398                 t_fmt_name = "<unknown>";
399         }
400 #endif
401
402         TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",
403                    tvee->model,
404                    tvee->rev_str,
405                    tvee->serial_number);
406         TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n",
407                    t_name,
408                    tuner,
409                    tvee->tuner_type);
410         TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n",
411                    t_fmt_name,
412                    t_format,
413                    tvee->tuner_formats);
414
415         TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n",
416                    STRM(sndtype,tvee->audio_processor),
417                    tvee->audio_processor);
418
419 }
420 EXPORT_SYMBOL(tveeprom_hauppauge_analog);
421
422 /* ----------------------------------------------------------------------- */
423 /* generic helper functions                                                */
424
425 int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
426 {
427         unsigned char buf;
428         int err;
429
430         dprintk(1, "%s\n",__FUNCTION__);
431         buf = 0;
432         if (1 != (err = i2c_master_send(c,&buf,1))) {
433                 printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n",
434                        c->name,err);
435                 return -1;
436         }
437         if (len != (err = i2c_master_recv(c,eedata,len))) {
438                 printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n",
439                        c->name,err);
440                 return -1;
441         }
442         return 0;
443 }
444 EXPORT_SYMBOL(tveeprom_read);
445
446 int tveeprom_dump(unsigned char *eedata, int len)
447 {
448         int i;
449
450         dprintk(1, "%s\n",__FUNCTION__);
451         for (i = 0; i < len; i++) {
452                 if (0 == (i % 16))
453                         printk(KERN_INFO "tveeprom: %02x:",i);
454                 printk(" %02x",eedata[i]);
455                 if (15 == (i % 16))
456                         printk("\n");
457         }
458         return 0;
459 }
460 EXPORT_SYMBOL(tveeprom_dump);
461
462 /* ----------------------------------------------------------------------- */
463 /* needed for ivtv.sf.net at the moment.  Should go away in the long       */
464 /* run, just call the exported tveeprom_* directly, there is no point in   */
465 /* using the indirect way via i2c_driver->command()                        */
466
467 #ifndef I2C_DRIVERID_TVEEPROM
468 # define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
469 #endif
470
471 static unsigned short normal_i2c[] = {
472         0xa0 >> 1,
473         I2C_CLIENT_END,
474 };
475 static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
476 I2C_CLIENT_INSMOD;
477
478 struct i2c_driver i2c_driver_tveeprom;
479
480 static int
481 tveeprom_command(struct i2c_client *client,
482                  unsigned int       cmd,
483                  void              *arg)
484 {
485         struct tveeprom eeprom;
486         u32 *eeprom_props = arg;
487         u8 *buf;
488
489         switch (cmd) {
490         case 0:
491                 buf = kmalloc(256,GFP_KERNEL);
492                 memset(buf,0,256);
493                 tveeprom_read(client,buf,256);
494                 tveeprom_hauppauge_analog(&eeprom,buf);
495                 kfree(buf);
496                 eeprom_props[0] = eeprom.tuner_type;
497                 eeprom_props[1] = eeprom.tuner_formats;
498                 eeprom_props[2] = eeprom.model;
499                 eeprom_props[3] = eeprom.revision;
500                 break;
501         default:
502                 return -EINVAL;
503         }
504         return 0;
505 }
506
507 static int
508 tveeprom_detect_client(struct i2c_adapter *adapter,
509                        int                 address,
510                        int                 kind)
511 {
512         struct i2c_client *client;
513
514         dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,
515                adapter->id, address << 1);
516         client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
517         if (NULL == client)
518                 return -ENOMEM;
519         memset(client, 0, sizeof(struct i2c_client));
520         client->addr = address;
521         client->adapter = adapter;
522         client->driver = &i2c_driver_tveeprom;
523         client->flags = I2C_CLIENT_ALLOW_USE;
524         snprintf(client->name, sizeof(client->name), "tveeprom");
525         i2c_attach_client(client);
526         return 0;
527 }
528
529 static int
530 tveeprom_attach_adapter (struct i2c_adapter *adapter)
531 {
532         dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);
533         if (adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))
534                 return 0;
535         return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
536 }
537
538 static int
539 tveeprom_detach_client (struct i2c_client *client)
540 {
541         int err;
542
543         err = i2c_detach_client(client);
544         if (err < 0)
545                 return err;
546         kfree(client);
547         return 0;
548 }
549
550 struct i2c_driver i2c_driver_tveeprom = {
551         .owner          = THIS_MODULE,
552         .name           = "tveeprom",
553         .id             = I2C_DRIVERID_TVEEPROM,
554         .flags          = I2C_DF_NOTIFY,
555         .attach_adapter = tveeprom_attach_adapter,
556         .detach_client  = tveeprom_detach_client,
557         .command        = tveeprom_command,
558 };
559
560 static int __init tveeprom_init(void)
561 {
562         return i2c_add_driver(&i2c_driver_tveeprom);
563 }
564
565 static void __exit tveeprom_exit(void)
566 {
567         i2c_del_driver(&i2c_driver_tveeprom);
568 }
569
570 module_init(tveeprom_init);
571 module_exit(tveeprom_exit);
572
573 /*
574  * Local variables:
575  * c-basic-offset: 8
576  * End:
577  */