linux/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *
   4 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   5 *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
   6 */
   7
   8#include <linux/slab.h>
   9#include "pvrusb2-eeprom.h"
  10#include "pvrusb2-hdw-internal.h"
  11#include "pvrusb2-debug.h"
  12
  13#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
  14
  15
  16
  17/*
  18
  19   Read and analyze data in the eeprom.  Use tveeprom to figure out
  20   the packet structure, since this is another Hauppauge device and
  21   internally it has a family resemblance to ivtv-type devices
  22
  23*/
  24
  25#include <media/tveeprom.h>
  26
  27/* We seem to only be interested in the last 128 bytes of the EEPROM */
  28#define EEPROM_SIZE 128
  29
  30/* Grab EEPROM contents, needed for direct method. */
  31static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
  32{
  33        struct i2c_msg msg[2];
  34        u8 *eeprom;
  35        u8 iadd[2];
  36        u8 addr;
  37        u16 eepromSize;
  38        unsigned int offs;
  39        int ret;
  40        int mode16 = 0;
  41        unsigned pcnt,tcnt;
  42        eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL);
  43        if (!eeprom) {
  44                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
  45                           "Failed to allocate memory required to read eeprom");
  46                return NULL;
  47        }
  48
  49        trace_eeprom("Value for eeprom addr from controller was 0x%x",
  50                     hdw->eeprom_addr);
  51        addr = hdw->eeprom_addr;
  52        /* Seems that if the high bit is set, then the *real* eeprom
  53           address is shifted right now bit position (noticed this in
  54           newer PVR USB2 hardware) */
  55        if (addr & 0x80) addr >>= 1;
  56
  57        /* FX2 documentation states that a 16bit-addressed eeprom is
  58           expected if the I2C address is an odd number (yeah, this is
  59           strange but it's what they do) */
  60        mode16 = (addr & 1);
  61        eepromSize = (mode16 ? 4096 : 256);
  62        trace_eeprom("Examining %d byte eeprom at location 0x%x using %d bit addressing",
  63                     eepromSize, addr,
  64                     mode16 ? 16 : 8);
  65
  66        msg[0].addr = addr;
  67        msg[0].flags = 0;
  68        msg[0].len = mode16 ? 2 : 1;
  69        msg[0].buf = iadd;
  70        msg[1].addr = addr;
  71        msg[1].flags = I2C_M_RD;
  72
  73        /* We have to do the actual eeprom data fetch ourselves, because
  74           (1) we're only fetching part of the eeprom, and (2) if we were
  75           getting the whole thing our I2C driver can't grab it in one
  76           pass - which is what tveeprom is otherwise going to attempt */
  77        for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
  78                pcnt = 16;
  79                if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
  80                offs = tcnt + (eepromSize - EEPROM_SIZE);
  81                if (mode16) {
  82                        iadd[0] = offs >> 8;
  83                        iadd[1] = offs;
  84                } else {
  85                        iadd[0] = offs;
  86                }
  87                msg[1].len = pcnt;
  88                msg[1].buf = eeprom+tcnt;
  89                if ((ret = i2c_transfer(&hdw->i2c_adap,
  90                                        msg,ARRAY_SIZE(msg))) != 2) {
  91                        pvr2_trace(PVR2_TRACE_ERROR_LEGS,
  92                                   "eeprom fetch set offs err=%d",ret);
  93                        kfree(eeprom);
  94                        return NULL;
  95                }
  96        }
  97        return eeprom;
  98}
  99
 100
 101/* Directly call eeprom analysis function within tveeprom. */
 102int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
 103{
 104        u8 *eeprom;
 105        struct tveeprom tvdata;
 106
 107        memset(&tvdata,0,sizeof(tvdata));
 108
 109        eeprom = pvr2_eeprom_fetch(hdw);
 110        if (!eeprom)
 111                return -EINVAL;
 112
 113        tveeprom_hauppauge_analog(&tvdata, eeprom);
 114
 115        trace_eeprom("eeprom assumed v4l tveeprom module");
 116        trace_eeprom("eeprom direct call results:");
 117        trace_eeprom("has_radio=%d",tvdata.has_radio);
 118        trace_eeprom("tuner_type=%d",tvdata.tuner_type);
 119        trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats);
 120        trace_eeprom("audio_processor=%d",tvdata.audio_processor);
 121        trace_eeprom("model=%d",tvdata.model);
 122        trace_eeprom("revision=%d",tvdata.revision);
 123        trace_eeprom("serial_number=%d",tvdata.serial_number);
 124        trace_eeprom("rev_str=%s",tvdata.rev_str);
 125        hdw->tuner_type = tvdata.tuner_type;
 126        hdw->tuner_updated = !0;
 127        hdw->serial_number = tvdata.serial_number;
 128        hdw->std_mask_eeprom = tvdata.tuner_formats;
 129
 130        kfree(eeprom);
 131
 132        return 0;
 133}
 134