1/*
2 * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
3 *
4 * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used)
5 *
6 * see flexcop.c for copyright information.
7 */
8#include "flexcop.h"
9
10
11static u8 calc_lrc(u8 *buf, int len)
12{
13	int i;
14	u8 sum = 0;
15	for (i = 0; i < len; i++)
16		sum = sum ^ buf[i];
17	return sum;
18}
19
20static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
21{
22	int i,ret = 0;
23	u8 chipaddr =  0x50 | ((addr >> 8) & 3);
24	for (i = 0; i < retries; i++)
25		if ((ret = fc->i2c_request(fc,op,FC_I2C_PORT_EEPROM,chipaddr,addr & 0xff,buf,len)) == 0)
26			break;
27	return ret;
28}
29
30static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
31{
32	int ret = flexcop_eeprom_request(fc,FC_READ,addr,buf,len,retries);
33	if (ret == 0)
34		if (calc_lrc(buf, len - 1) != buf[len - 1])
35			ret = -EINVAL;
36	return ret;
37}
38
39/* JJ's comment about extended == 1: it is not presently used anywhere but was
40 * added to the low-level functions for possible support of EUI64
41 */
42int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
43{
44	u8 buf[8];
45	int ret = 0;
46
47	if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
48		if (extended != 0) {
49			err("TODO: extended (EUI64) MAC addresses aren't completely supported yet");
50			ret = -EINVAL;
51/*			memcpy(fc->dvb_adapter.proposed_mac,buf,3);
52			mac[3] = 0xfe;
53			mac[4] = 0xff;
54			memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */
55		} else
56			memcpy(fc->dvb_adapter.proposed_mac,buf,6);
57	}
58	return ret;
59}
60EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
61