Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/b2c2/flexcop-eeprom.c
15111 views
1
/*
2
* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3
* flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
4
* see flexcop.c for copyright information
5
*/
6
#include "flexcop.h"
7
8
#if 0
9
/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
10
static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
11
{
12
return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
13
}
14
15
static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
16
u32 len, u8 *wbuf, u8 *rbuf, int retries)
17
{
18
int i;
19
20
for (i = 0; i < retries; i++) {
21
if (eeprom_write(adapter, addr, wbuf, len) == len) {
22
if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
23
return 1;
24
}
25
}
26
return 0;
27
}
28
29
/* These functions could be used to unlock SkyStar2 cards. */
30
31
static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
32
{
33
u8 rbuf[20];
34
u8 wbuf[20];
35
36
if (len != 16)
37
return 0;
38
39
memcpy(wbuf, key, len);
40
wbuf[16] = 0;
41
wbuf[17] = 0;
42
wbuf[18] = 0;
43
wbuf[19] = calc_lrc(wbuf, 19);
44
return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
45
}
46
47
static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
48
{
49
u8 buf[20];
50
51
if (len != 16)
52
return 0;
53
54
if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
55
return 0;
56
57
memcpy(key, buf, len);
58
return 1;
59
}
60
61
static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
62
{
63
u8 tmp[8];
64
65
if (type != 0) {
66
tmp[0] = mac[0];
67
tmp[1] = mac[1];
68
tmp[2] = mac[2];
69
tmp[3] = mac[5];
70
tmp[4] = mac[6];
71
tmp[5] = mac[7];
72
} else {
73
tmp[0] = mac[0];
74
tmp[1] = mac[1];
75
tmp[2] = mac[2];
76
tmp[3] = mac[3];
77
tmp[4] = mac[4];
78
tmp[5] = mac[5];
79
}
80
81
tmp[6] = 0;
82
tmp[7] = calc_lrc(tmp, 7);
83
84
if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
85
return 1;
86
return 0;
87
}
88
89
static int flexcop_eeprom_read(struct flexcop_device *fc,
90
u16 addr, u8 *buf, u16 len)
91
{
92
return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
93
}
94
95
#endif
96
97
static u8 calc_lrc(u8 *buf, int len)
98
{
99
int i;
100
u8 sum = 0;
101
for (i = 0; i < len; i++)
102
sum = sum ^ buf[i];
103
return sum;
104
}
105
106
static int flexcop_eeprom_request(struct flexcop_device *fc,
107
flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
108
{
109
int i,ret = 0;
110
u8 chipaddr = 0x50 | ((addr >> 8) & 3);
111
for (i = 0; i < retries; i++) {
112
ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
113
addr & 0xff, buf, len);
114
if (ret == 0)
115
break;
116
}
117
return ret;
118
}
119
120
static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
121
u8 *buf, u16 len, int retries)
122
{
123
int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
124
if (ret == 0)
125
if (calc_lrc(buf, len - 1) != buf[len - 1])
126
ret = -EINVAL;
127
return ret;
128
}
129
130
/* JJ's comment about extended == 1: it is not presently used anywhere but was
131
* added to the low-level functions for possible support of EUI64 */
132
int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
133
{
134
u8 buf[8];
135
int ret = 0;
136
137
if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
138
if (extended != 0) {
139
err("TODO: extended (EUI64) MAC addresses aren't "
140
"completely supported yet");
141
ret = -EINVAL;
142
} else
143
memcpy(fc->dvb_adapter.proposed_mac,buf,6);
144
}
145
return ret;
146
}
147
EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
148
149