1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "pvrusb2-eeprom.h"
23#include "pvrusb2-hdw-internal.h"
24#include "pvrusb2-debug.h"
25
26#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
27
28
29
30
31
32
33
34
35
36
37
38#include <media/tveeprom.h>
39
40
41#define EEPROM_SIZE 128
42
43
44static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
45{
46 struct i2c_msg msg[2];
47 u8 *eeprom;
48 u8 iadd[2];
49 u8 addr;
50 u16 eepromSize;
51 unsigned int offs;
52 int ret;
53 int mode16 = 0;
54 unsigned pcnt,tcnt;
55 eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
56 if (!eeprom) {
57 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
58 "Failed to allocate memory"
59 " required to read eeprom");
60 return NULL;
61 }
62
63 trace_eeprom("Value for eeprom addr from controller was 0x%x",
64 hdw->eeprom_addr);
65 addr = hdw->eeprom_addr;
66
67
68
69 if (addr & 0x80) addr >>= 1;
70
71
72
73
74 mode16 = (addr & 1);
75 eepromSize = (mode16 ? 4096 : 256);
76 trace_eeprom("Examining %d byte eeprom at location 0x%x"
77 " using %d bit addressing",eepromSize,addr,
78 mode16 ? 16 : 8);
79
80 msg[0].addr = addr;
81 msg[0].flags = 0;
82 msg[0].len = mode16 ? 2 : 1;
83 msg[0].buf = iadd;
84 msg[1].addr = addr;
85 msg[1].flags = I2C_M_RD;
86
87
88
89
90
91 memset(eeprom,0,EEPROM_SIZE);
92 for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
93 pcnt = 16;
94 if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
95 offs = tcnt + (eepromSize - EEPROM_SIZE);
96 if (mode16) {
97 iadd[0] = offs >> 8;
98 iadd[1] = offs;
99 } else {
100 iadd[0] = offs;
101 }
102 msg[1].len = pcnt;
103 msg[1].buf = eeprom+tcnt;
104 if ((ret = i2c_transfer(&hdw->i2c_adap,
105 msg,ARRAY_SIZE(msg))) != 2) {
106 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
107 "eeprom fetch set offs err=%d",ret);
108 kfree(eeprom);
109 return NULL;
110 }
111 }
112 return eeprom;
113}
114
115
116
117int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
118{
119 u8 *eeprom;
120 struct tveeprom tvdata;
121
122 memset(&tvdata,0,sizeof(tvdata));
123
124 eeprom = pvr2_eeprom_fetch(hdw);
125 if (!eeprom) return -EINVAL;
126
127 {
128 struct i2c_client fake_client;
129
130 fake_client.addr = hdw->eeprom_addr;
131 fake_client.adapter = &hdw->i2c_adap;
132 tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
133 }
134
135 trace_eeprom("eeprom assumed v4l tveeprom module");
136 trace_eeprom("eeprom direct call results:");
137 trace_eeprom("has_radio=%d",tvdata.has_radio);
138 trace_eeprom("tuner_type=%d",tvdata.tuner_type);
139 trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats);
140 trace_eeprom("audio_processor=%d",tvdata.audio_processor);
141 trace_eeprom("model=%d",tvdata.model);
142 trace_eeprom("revision=%d",tvdata.revision);
143 trace_eeprom("serial_number=%d",tvdata.serial_number);
144 trace_eeprom("rev_str=%s",tvdata.rev_str);
145 hdw->tuner_type = tvdata.tuner_type;
146 hdw->tuner_updated = !0;
147 hdw->serial_number = tvdata.serial_number;
148 hdw->std_mask_eeprom = tvdata.tuner_formats;
149
150 kfree(eeprom);
151
152 return 0;
153}
154
155
156
157
158
159
160
161
162
163
164