Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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