/* * Copyright 2013 GE Intelligent Platforms Inc. * Copyright 2019 Abaco Systems Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Retrieve and check the product data. */ #include #include #include #include #include #include "product_data.h" static int owc_pd_header_check(unsigned short header) { if (header != 0xa5a5) return -1; else return 0; } static int owc_is_data_valid(struct owc_product_data *v) { int crc, ret = 0; const unsigned char *p = (const unsigned char *)v; if (owc_pd_header_check(v->v1.pdh.tag)) return -1; switch (v->v1.pdh.version) { case PDVERSION_V1: case PDVERSION_V1bis: crc = crc32(0, p, sizeof(struct product_data_v1) - 4); if (crc != v->v1.crc32) ret = -1; break; case PDVERSION_V2: crc = crc32(0, p, sizeof(struct product_data_v2) - 4); if (crc != v->v2.crc32) ret = -1; break; default: ret = -1; } return ret; } int owc_get_product_data(struct owc_product_data *productp) { struct i2c_adapter *adapter; struct i2c_client client; unsigned int width = 0; int ret; adapter = i2c_get_adapter(0); client.addr = 0x51; client.adapter = adapter; ret = i2c_read_reg(&client, 0, (uint8_t *) productp, sizeof(unsigned short)); /* If there is no valid header, it may be a 16-bit eeprom. */ if (owc_pd_header_check(productp->v1.pdh.tag)) width = I2C_ADDR_16_BIT; ret = i2c_read_reg(&client, width, (uint8_t *) productp, sizeof(struct owc_product_data)); if (ret == sizeof(struct owc_product_data)) ret = owc_is_data_valid(productp); return ret; }