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