diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-10-05 16:36:26 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-10-05 16:36:26 +0400 |
commit | bd0d10498826ed150da5e4c45baf8b9c7088fb71 (patch) | |
tree | cdee4371121a355d627a655c4eef5c0047b0462a /drivers/media/common/b2c2/flexcop-eeprom.c | |
parent | 89de0f2cda8b784e51ebd6655fff7339e4ac552b (diff) | |
parent | 2425bb3d4016ed95ce83a90b53bd92c7f31091e4 (diff) | |
download | linux-bd0d10498826ed150da5e4c45baf8b9c7088fb71.tar.xz |
Merge branch 'staging/for_v3.7' into v4l_for_linus
* staging/for_v3.7: (2891 commits)
em28xx: regression fix: use DRX-K sync firmware requests on em28xx
drxk: allow loading firmware synchrousnously
em28xx: Make all em28xx extensions to be initialized asynchronously
[media] tda18271: properly report read errors in tda18271_get_id
[media] tda18271: delay IR & RF calibration until init() if delay_cal is set
[media] MAINTAINERS: add Michael Krufky as tda827x maintainer
[media] MAINTAINERS: add Michael Krufky as tda8290 maintainer
[media] MAINTAINERS: add Michael Krufky as cxusb maintainer
[media] MAINTAINERS: add Michael Krufky as lg2160 maintainer
[media] MAINTAINERS: add Michael Krufky as lgdt3305 maintainer
[media] MAINTAINERS: add Michael Krufky as mxl111sf maintainer
[media] MAINTAINERS: add Michael Krufky as mxl5007t maintainer
[media] MAINTAINERS: add Michael Krufky as tda18271 maintainer
[media] s5p-tv: Report only multi-plane capabilities in vidioc_querycap
[media] s5p-mfc: Fix misplaced return statement in s5p_mfc_suspend()
[media] exynos-gsc: Add missing static storage class specifiers
[media] exynos-gsc: Remove <linux/version.h> header file inclusion
[media] s5p-fimc: Fix incorrect condition in fimc_lite_reqbufs()
[media] s5p-tv: Fix potential NULL pointer dereference error
[media] s5k6aa: Fix possible NULL pointer dereference
...
Conflicts:
drivers/media/platform/s5p-fimc/fimc-capture.c
drivers/media/platform/s5p-fimc/fimc-lite.c
Diffstat (limited to 'drivers/media/common/b2c2/flexcop-eeprom.c')
-rw-r--r-- | drivers/media/common/b2c2/flexcop-eeprom.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c new file mode 100644 index 000000000000..a25373a9bd84 --- /dev/null +++ b/drivers/media/common/b2c2/flexcop-eeprom.c @@ -0,0 +1,147 @@ +/* + * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III + * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading) + * see flexcop.c for copyright information + */ +#include "flexcop.h" + +#if 0 +/*EEPROM (Skystar2 has one "24LC08B" chip on board) */ +static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len) +{ + return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len); +} + +static int eeprom_lrc_write(struct adapter *adapter, u32 addr, + u32 len, u8 *wbuf, u8 *rbuf, int retries) +{ +int i; + +for (i = 0; i < retries; i++) { + if (eeprom_write(adapter, addr, wbuf, len) == len) { + if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) + return 1; + } + } + return 0; +} + +/* These functions could be used to unlock SkyStar2 cards. */ + +static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len) +{ + u8 rbuf[20]; + u8 wbuf[20]; + + if (len != 16) + return 0; + + memcpy(wbuf, key, len); + wbuf[16] = 0; + wbuf[17] = 0; + wbuf[18] = 0; + wbuf[19] = calc_lrc(wbuf, 19); + return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4); +} + +static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len) +{ + u8 buf[20]; + + if (len != 16) + return 0; + + if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0) + return 0; + + memcpy(key, buf, len); + return 1; +} + +static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) +{ + u8 tmp[8]; + + if (type != 0) { + tmp[0] = mac[0]; + tmp[1] = mac[1]; + tmp[2] = mac[2]; + tmp[3] = mac[5]; + tmp[4] = mac[6]; + tmp[5] = mac[7]; + } else { + tmp[0] = mac[0]; + tmp[1] = mac[1]; + tmp[2] = mac[2]; + tmp[3] = mac[3]; + tmp[4] = mac[4]; + tmp[5] = mac[5]; + } + + tmp[6] = 0; + tmp[7] = calc_lrc(tmp, 7); + + if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8) + return 1; + return 0; +} + +static int flexcop_eeprom_read(struct flexcop_device *fc, + u16 addr, u8 *buf, u16 len) +{ + return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len); +} + +#endif + +static u8 calc_lrc(u8 *buf, int len) +{ + int i; + u8 sum = 0; + for (i = 0; i < len; i++) + sum = sum ^ buf[i]; + return sum; +} + +static int flexcop_eeprom_request(struct flexcop_device *fc, + flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) +{ + int i,ret = 0; + u8 chipaddr = 0x50 | ((addr >> 8) & 3); + for (i = 0; i < retries; i++) { + ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr, + addr & 0xff, buf, len); + if (ret == 0) + break; + } + return ret; +} + +static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, + u8 *buf, u16 len, int retries) +{ + int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries); + if (ret == 0) + if (calc_lrc(buf, len - 1) != buf[len - 1]) + ret = -EINVAL; + return ret; +} + +/* JJ's comment about extended == 1: it is not presently used anywhere but was + * added to the low-level functions for possible support of EUI64 */ +int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) +{ + u8 buf[8]; + int ret = 0; + + if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) { + if (extended != 0) { + err("TODO: extended (EUI64) MAC addresses aren't " + "completely supported yet"); + ret = -EINVAL; + } else + memcpy(fc->dvb_adapter.proposed_mac,buf,6); + } + return ret; +} +EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr); |