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