Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
0005  *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
0006  */
0007 
0008 #include <linux/slab.h>
0009 #include "pvrusb2-eeprom.h"
0010 #include "pvrusb2-hdw-internal.h"
0011 #include "pvrusb2-debug.h"
0012 
0013 #define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
0014 
0015 
0016 
0017 /*
0018 
0019    Read and analyze data in the eeprom.  Use tveeprom to figure out
0020    the packet structure, since this is another Hauppauge device and
0021    internally it has a family resemblance to ivtv-type devices
0022 
0023 */
0024 
0025 #include <media/tveeprom.h>
0026 
0027 /* We seem to only be interested in the last 128 bytes of the EEPROM */
0028 #define EEPROM_SIZE 128
0029 
0030 /* Grab EEPROM contents, needed for direct method. */
0031 static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
0032 {
0033     struct i2c_msg msg[2];
0034     u8 *eeprom;
0035     u8 iadd[2];
0036     u8 addr;
0037     u16 eepromSize;
0038     unsigned int offs;
0039     int ret;
0040     int mode16 = 0;
0041     unsigned pcnt,tcnt;
0042     eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL);
0043     if (!eeprom) {
0044         pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0045                "Failed to allocate memory required to read eeprom");
0046         return NULL;
0047     }
0048 
0049     trace_eeprom("Value for eeprom addr from controller was 0x%x",
0050              hdw->eeprom_addr);
0051     addr = hdw->eeprom_addr;
0052     /* Seems that if the high bit is set, then the *real* eeprom
0053        address is shifted right now bit position (noticed this in
0054        newer PVR USB2 hardware) */
0055     if (addr & 0x80) addr >>= 1;
0056 
0057     /* FX2 documentation states that a 16bit-addressed eeprom is
0058        expected if the I2C address is an odd number (yeah, this is
0059        strange but it's what they do) */
0060     mode16 = (addr & 1);
0061     eepromSize = (mode16 ? 4096 : 256);
0062     trace_eeprom("Examining %d byte eeprom at location 0x%x using %d bit addressing",
0063              eepromSize, addr,
0064              mode16 ? 16 : 8);
0065 
0066     msg[0].addr = addr;
0067     msg[0].flags = 0;
0068     msg[0].len = mode16 ? 2 : 1;
0069     msg[0].buf = iadd;
0070     msg[1].addr = addr;
0071     msg[1].flags = I2C_M_RD;
0072 
0073     /* We have to do the actual eeprom data fetch ourselves, because
0074        (1) we're only fetching part of the eeprom, and (2) if we were
0075        getting the whole thing our I2C driver can't grab it in one
0076        pass - which is what tveeprom is otherwise going to attempt */
0077     for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
0078         pcnt = 16;
0079         if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
0080         offs = tcnt + (eepromSize - EEPROM_SIZE);
0081         if (mode16) {
0082             iadd[0] = offs >> 8;
0083             iadd[1] = offs;
0084         } else {
0085             iadd[0] = offs;
0086         }
0087         msg[1].len = pcnt;
0088         msg[1].buf = eeprom+tcnt;
0089         if ((ret = i2c_transfer(&hdw->i2c_adap,
0090                     msg,ARRAY_SIZE(msg))) != 2) {
0091             pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0092                    "eeprom fetch set offs err=%d",ret);
0093             kfree(eeprom);
0094             return NULL;
0095         }
0096     }
0097     return eeprom;
0098 }
0099 
0100 
0101 /* Directly call eeprom analysis function within tveeprom. */
0102 int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
0103 {
0104     u8 *eeprom;
0105     struct tveeprom tvdata;
0106 
0107     memset(&tvdata,0,sizeof(tvdata));
0108 
0109     eeprom = pvr2_eeprom_fetch(hdw);
0110     if (!eeprom)
0111         return -EINVAL;
0112 
0113     tveeprom_hauppauge_analog(&tvdata, eeprom);
0114 
0115     trace_eeprom("eeprom assumed v4l tveeprom module");
0116     trace_eeprom("eeprom direct call results:");
0117     trace_eeprom("has_radio=%d",tvdata.has_radio);
0118     trace_eeprom("tuner_type=%d",tvdata.tuner_type);
0119     trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats);
0120     trace_eeprom("audio_processor=%d",tvdata.audio_processor);
0121     trace_eeprom("model=%d",tvdata.model);
0122     trace_eeprom("revision=%d",tvdata.revision);
0123     trace_eeprom("serial_number=%d",tvdata.serial_number);
0124     trace_eeprom("rev_str=%s",tvdata.rev_str);
0125     hdw->tuner_type = tvdata.tuner_type;
0126     hdw->tuner_updated = !0;
0127     hdw->serial_number = tvdata.serial_number;
0128     hdw->std_mask_eeprom = tvdata.tuner_formats;
0129 
0130     kfree(eeprom);
0131 
0132     return 0;
0133 }