Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 
0003 /*
0004  *
0005  * cx88-i2c.c  --  all the i2c code is here
0006  *
0007  * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
0008  *             & Marcus Metzler (mocm@thp.uni-koeln.de)
0009  * (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
0010  * (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
0011  * (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org>
0012  *  - Multituner support and i2c address binding
0013  */
0014 
0015 #include "cx88.h"
0016 
0017 #include <linux/init.h>
0018 #include <linux/io.h>
0019 #include <linux/module.h>
0020 
0021 #include <media/v4l2-common.h>
0022 
0023 static unsigned int i2c_debug;
0024 module_param(i2c_debug, int, 0644);
0025 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
0026 
0027 static unsigned int i2c_scan;
0028 module_param(i2c_scan, int, 0444);
0029 MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
0030 
0031 static unsigned int i2c_udelay = 5;
0032 module_param(i2c_udelay, int, 0644);
0033 MODULE_PARM_DESC(i2c_udelay,
0034          "i2c delay at insmod time, in usecs (should be 5 or higher). Lower value means higher bus speed.");
0035 
0036 #define dprintk(level, fmt, arg...) do {                \
0037     if (i2c_debug >= level)                     \
0038         printk(KERN_DEBUG pr_fmt("%s: i2c:" fmt),       \
0039             __func__, ##arg);               \
0040 } while (0)
0041 
0042 /* ----------------------------------------------------------------------- */
0043 
0044 static void cx8800_bit_setscl(void *data, int state)
0045 {
0046     struct cx88_core *core = data;
0047 
0048     if (state)
0049         core->i2c_state |= 0x02;
0050     else
0051         core->i2c_state &= ~0x02;
0052     cx_write(MO_I2C, core->i2c_state);
0053     cx_read(MO_I2C);
0054 }
0055 
0056 static void cx8800_bit_setsda(void *data, int state)
0057 {
0058     struct cx88_core *core = data;
0059 
0060     if (state)
0061         core->i2c_state |= 0x01;
0062     else
0063         core->i2c_state &= ~0x01;
0064     cx_write(MO_I2C, core->i2c_state);
0065     cx_read(MO_I2C);
0066 }
0067 
0068 static int cx8800_bit_getscl(void *data)
0069 {
0070     struct cx88_core *core = data;
0071     u32 state;
0072 
0073     state = cx_read(MO_I2C);
0074     return state & 0x02 ? 1 : 0;
0075 }
0076 
0077 static int cx8800_bit_getsda(void *data)
0078 {
0079     struct cx88_core *core = data;
0080     u32 state;
0081 
0082     state = cx_read(MO_I2C);
0083     return state & 0x01;
0084 }
0085 
0086 /* ----------------------------------------------------------------------- */
0087 
0088 static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
0089     .setsda  = cx8800_bit_setsda,
0090     .setscl  = cx8800_bit_setscl,
0091     .getsda  = cx8800_bit_getsda,
0092     .getscl  = cx8800_bit_getscl,
0093     .udelay  = 16,
0094     .timeout = 200,
0095 };
0096 
0097 /* ----------------------------------------------------------------------- */
0098 
0099 static const char * const i2c_devs[128] = {
0100     [0x1c >> 1] = "lgdt330x",
0101     [0x86 >> 1] = "tda9887/cx22702",
0102     [0xa0 >> 1] = "eeprom",
0103     [0xc0 >> 1] = "tuner (analog)",
0104     [0xc2 >> 1] = "tuner (analog/dvb)",
0105     [0xc8 >> 1] = "xc5000",
0106 };
0107 
0108 static void do_i2c_scan(const char *name, struct i2c_client *c)
0109 {
0110     unsigned char buf;
0111     int i, rc;
0112 
0113     for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
0114         c->addr = i;
0115         rc = i2c_master_recv(c, &buf, 0);
0116         if (rc < 0)
0117             continue;
0118         pr_info("i2c scan: found device @ 0x%x  [%s]\n",
0119             i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
0120     }
0121 }
0122 
0123 /* init + register i2c adapter */
0124 int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
0125 {
0126     /* Prevents usage of invalid delay values */
0127     if (i2c_udelay < 5)
0128         i2c_udelay = 5;
0129 
0130     core->i2c_algo = cx8800_i2c_algo_template;
0131 
0132     core->i2c_adap.dev.parent = &pci->dev;
0133     strscpy(core->i2c_adap.name, core->name, sizeof(core->i2c_adap.name));
0134     core->i2c_adap.owner = THIS_MODULE;
0135     core->i2c_algo.udelay = i2c_udelay;
0136     core->i2c_algo.data = core;
0137     i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
0138     core->i2c_adap.algo_data = &core->i2c_algo;
0139     core->i2c_client.adapter = &core->i2c_adap;
0140     strscpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
0141 
0142     cx8800_bit_setscl(core, 1);
0143     cx8800_bit_setsda(core, 1);
0144 
0145     core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);
0146     if (core->i2c_rc == 0) {
0147         static u8 tuner_data[] = {
0148             0x0b, 0xdc, 0x86, 0x52 };
0149         static struct i2c_msg tuner_msg = {
0150             .flags = 0,
0151             .addr = 0xc2 >> 1,
0152             .buf = tuner_data,
0153             .len = 4
0154         };
0155 
0156         dprintk(1, "i2c register ok\n");
0157         switch (core->boardnr) {
0158         case CX88_BOARD_HAUPPAUGE_HVR1300:
0159         case CX88_BOARD_HAUPPAUGE_HVR3000:
0160         case CX88_BOARD_HAUPPAUGE_HVR4000:
0161             pr_info("i2c init: enabling analog demod on HVR1300/3000/4000 tuner\n");
0162             i2c_transfer(core->i2c_client.adapter, &tuner_msg, 1);
0163             break;
0164         default:
0165             break;
0166         }
0167         if (i2c_scan)
0168             do_i2c_scan(core->name, &core->i2c_client);
0169     } else
0170         pr_err("i2c register FAILED\n");
0171 
0172     return core->i2c_rc;
0173 }