Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0003 
0004 #include <linux/i2c.h>
0005 #include <linux/mutex.h>
0006 #include <linux/module.h>
0007 
0008 #include "dibx000_common.h"
0009 
0010 static int debug;
0011 module_param(debug, int, 0644);
0012 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
0013 
0014 #define dprintk(fmt, arg...) do {                   \
0015     if (debug)                          \
0016         printk(KERN_DEBUG pr_fmt("%s: " fmt),           \
0017                __func__, ##arg);                \
0018 } while (0)
0019 
0020 static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
0021 {
0022     int ret;
0023 
0024     if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0025         dprintk("could not acquire lock\n");
0026         return -EINVAL;
0027     }
0028 
0029     mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
0030     mst->i2c_write_buffer[1] = reg & 0xff;
0031     mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
0032     mst->i2c_write_buffer[3] = val & 0xff;
0033 
0034     memset(mst->msg, 0, sizeof(struct i2c_msg));
0035     mst->msg[0].addr = mst->i2c_addr;
0036     mst->msg[0].flags = 0;
0037     mst->msg[0].buf = mst->i2c_write_buffer;
0038     mst->msg[0].len = 4;
0039 
0040     ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
0041     mutex_unlock(&mst->i2c_buffer_lock);
0042 
0043     return ret;
0044 }
0045 
0046 static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
0047 {
0048     u16 ret;
0049 
0050     if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0051         dprintk("could not acquire lock\n");
0052         return 0;
0053     }
0054 
0055     mst->i2c_write_buffer[0] = reg >> 8;
0056     mst->i2c_write_buffer[1] = reg & 0xff;
0057 
0058     memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
0059     mst->msg[0].addr = mst->i2c_addr;
0060     mst->msg[0].flags = 0;
0061     mst->msg[0].buf = mst->i2c_write_buffer;
0062     mst->msg[0].len = 2;
0063     mst->msg[1].addr = mst->i2c_addr;
0064     mst->msg[1].flags = I2C_M_RD;
0065     mst->msg[1].buf = mst->i2c_read_buffer;
0066     mst->msg[1].len = 2;
0067 
0068     if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
0069         dprintk("i2c read error on %d\n", reg);
0070 
0071     ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
0072     mutex_unlock(&mst->i2c_buffer_lock);
0073 
0074     return ret;
0075 }
0076 
0077 static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
0078 {
0079     int i = 100;
0080     u16 status;
0081 
0082     while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
0083         ;
0084 
0085     /* i2c timed out */
0086     if (i == 0)
0087         return -EREMOTEIO;
0088 
0089     /* no acknowledge */
0090     if ((status & 0x0080) == 0)
0091         return -EREMOTEIO;
0092 
0093     return 0;
0094 }
0095 
0096 static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
0097 {
0098     u16 data;
0099     u16 da;
0100     u16 i;
0101     u16 txlen = msg->len, len;
0102     const u8 *b = msg->buf;
0103 
0104     while (txlen) {
0105         dibx000_read_word(mst, mst->base_reg + 2);
0106 
0107         len = txlen > 8 ? 8 : txlen;
0108         for (i = 0; i < len; i += 2) {
0109             data = *b++ << 8;
0110             if (i+1 < len)
0111                 data |= *b++;
0112             dibx000_write_word(mst, mst->base_reg, data);
0113         }
0114         da = (((u8) (msg->addr))  << 9) |
0115             (1           << 8) |
0116             (1           << 7) |
0117             (0           << 6) |
0118             (0           << 5) |
0119             ((len & 0x7) << 2) |
0120             (0           << 1) |
0121             (0           << 0);
0122 
0123         if (txlen == msg->len)
0124             da |= 1 << 5; /* start */
0125 
0126         if (txlen-len == 0 && stop)
0127             da |= 1 << 6; /* stop */
0128 
0129         dibx000_write_word(mst, mst->base_reg+1, da);
0130 
0131         if (dibx000_is_i2c_done(mst) != 0)
0132             return -EREMOTEIO;
0133         txlen -= len;
0134     }
0135 
0136     return 0;
0137 }
0138 
0139 static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
0140 {
0141     u16 da;
0142     u8 *b = msg->buf;
0143     u16 rxlen = msg->len, len;
0144 
0145     while (rxlen) {
0146         len = rxlen > 8 ? 8 : rxlen;
0147         da = (((u8) (msg->addr)) << 9) |
0148             (1           << 8) |
0149             (1           << 7) |
0150             (0           << 6) |
0151             (0           << 5) |
0152             ((len & 0x7) << 2) |
0153             (1           << 1) |
0154             (0           << 0);
0155 
0156         if (rxlen == msg->len)
0157             da |= 1 << 5; /* start */
0158 
0159         if (rxlen-len == 0)
0160             da |= 1 << 6; /* stop */
0161         dibx000_write_word(mst, mst->base_reg+1, da);
0162 
0163         if (dibx000_is_i2c_done(mst) != 0)
0164             return -EREMOTEIO;
0165 
0166         rxlen -= len;
0167 
0168         while (len) {
0169             da = dibx000_read_word(mst, mst->base_reg);
0170             *b++ = (da >> 8) & 0xff;
0171             len--;
0172             if (len >= 1) {
0173                 *b++ =  da   & 0xff;
0174                 len--;
0175             }
0176         }
0177     }
0178 
0179     return 0;
0180 }
0181 
0182 int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
0183 {
0184     struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0185 
0186     if (mst->device_rev < DIB7000MC && speed < 235)
0187         speed = 235;
0188     return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
0189 
0190 }
0191 EXPORT_SYMBOL(dibx000_i2c_set_speed);
0192 
0193 static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
0194 {
0195     return I2C_FUNC_I2C;
0196 }
0197 
0198 static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
0199                     enum dibx000_i2c_interface intf)
0200 {
0201     if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
0202         dprintk("selecting interface: %d\n", intf);
0203         mst->selected_interface = intf;
0204         return dibx000_write_word(mst, mst->base_reg + 4, intf);
0205     }
0206     return 0;
0207 }
0208 
0209 static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
0210 {
0211     struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0212     int msg_index;
0213     int ret = 0;
0214 
0215     dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
0216     for (msg_index = 0; msg_index < num; msg_index++) {
0217         if (msg[msg_index].flags & I2C_M_RD) {
0218             ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
0219             if (ret != 0)
0220                 return 0;
0221         } else {
0222             ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
0223             if (ret != 0)
0224                 return 0;
0225         }
0226     }
0227 
0228     return num;
0229 }
0230 
0231 static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
0232 {
0233     struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0234     int msg_index;
0235     int ret = 0;
0236 
0237     dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
0238     for (msg_index = 0; msg_index < num; msg_index++) {
0239         if (msg[msg_index].flags & I2C_M_RD) {
0240             ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
0241             if (ret != 0)
0242                 return 0;
0243         } else {
0244             ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
0245             if (ret != 0)
0246                 return 0;
0247         }
0248     }
0249 
0250     return num;
0251 }
0252 
0253 static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
0254     .master_xfer = dibx000_i2c_master_xfer_gpio12,
0255     .functionality = dibx000_i2c_func,
0256 };
0257 
0258 static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
0259     .master_xfer = dibx000_i2c_master_xfer_gpio34,
0260     .functionality = dibx000_i2c_func,
0261 };
0262 
0263 static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
0264                  u8 addr, int onoff)
0265 {
0266     u16 val;
0267 
0268 
0269     if (onoff)
0270         val = addr << 8;    // bit 7 = use master or not, if 0, the gate is open
0271     else
0272         val = 1 << 7;
0273 
0274     if (mst->device_rev > DIB7000)
0275         val <<= 1;
0276 
0277     tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
0278     tx[1] = ((mst->base_reg + 1) & 0xff);
0279     tx[2] = val >> 8;
0280     tx[3] = val & 0xff;
0281 
0282     return 0;
0283 }
0284 
0285 static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
0286                     struct i2c_msg msg[], int num)
0287 {
0288     struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0289     int ret;
0290 
0291     if (num > 32) {
0292         dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
0293             __func__, num);
0294         return -ENOMEM;
0295     }
0296 
0297     dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
0298 
0299     if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0300         dprintk("could not acquire lock\n");
0301         return -EINVAL;
0302     }
0303 
0304     memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
0305 
0306     /* open the gate */
0307     dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
0308     mst->msg[0].addr = mst->i2c_addr;
0309     mst->msg[0].buf = &mst->i2c_write_buffer[0];
0310     mst->msg[0].len = 4;
0311 
0312     memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
0313 
0314     /* close the gate */
0315     dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
0316     mst->msg[num + 1].addr = mst->i2c_addr;
0317     mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
0318     mst->msg[num + 1].len = 4;
0319 
0320     ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
0321             num : -EIO);
0322 
0323     mutex_unlock(&mst->i2c_buffer_lock);
0324     return ret;
0325 }
0326 
0327 static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
0328     .master_xfer = dibx000_i2c_gated_gpio67_xfer,
0329     .functionality = dibx000_i2c_func,
0330 };
0331 
0332 static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
0333                     struct i2c_msg msg[], int num)
0334 {
0335     struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0336     int ret;
0337 
0338     if (num > 32) {
0339         dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
0340             __func__, num);
0341         return -ENOMEM;
0342     }
0343 
0344     dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
0345 
0346     if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0347         dprintk("could not acquire lock\n");
0348         return -EINVAL;
0349     }
0350     memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
0351 
0352     /* open the gate */
0353     dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
0354     mst->msg[0].addr = mst->i2c_addr;
0355     mst->msg[0].buf = &mst->i2c_write_buffer[0];
0356     mst->msg[0].len = 4;
0357 
0358     memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
0359 
0360     /* close the gate */
0361     dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
0362     mst->msg[num + 1].addr = mst->i2c_addr;
0363     mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
0364     mst->msg[num + 1].len = 4;
0365 
0366     ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
0367             num : -EIO);
0368     mutex_unlock(&mst->i2c_buffer_lock);
0369     return ret;
0370 }
0371 
0372 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
0373     .master_xfer = dibx000_i2c_gated_tuner_xfer,
0374     .functionality = dibx000_i2c_func,
0375 };
0376 
0377 struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
0378                         enum dibx000_i2c_interface intf,
0379                         int gating)
0380 {
0381     struct i2c_adapter *i2c = NULL;
0382 
0383     switch (intf) {
0384     case DIBX000_I2C_INTERFACE_TUNER:
0385         if (gating)
0386             i2c = &mst->gated_tuner_i2c_adap;
0387         break;
0388     case DIBX000_I2C_INTERFACE_GPIO_1_2:
0389         if (!gating)
0390             i2c = &mst->master_i2c_adap_gpio12;
0391         break;
0392     case DIBX000_I2C_INTERFACE_GPIO_3_4:
0393         if (!gating)
0394             i2c = &mst->master_i2c_adap_gpio34;
0395         break;
0396     case DIBX000_I2C_INTERFACE_GPIO_6_7:
0397         if (gating)
0398             i2c = &mst->master_i2c_adap_gpio67;
0399         break;
0400     default:
0401         pr_err("incorrect I2C interface selected\n");
0402         break;
0403     }
0404 
0405     return i2c;
0406 }
0407 
0408 EXPORT_SYMBOL(dibx000_get_i2c_adapter);
0409 
0410 void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
0411 {
0412     /* initialize the i2c-master by closing the gate */
0413     u8 tx[4];
0414     struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
0415 
0416     dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
0417     i2c_transfer(mst->i2c_adap, &m, 1);
0418     mst->selected_interface = 0xff; // the first time force a select of the I2C
0419     dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
0420 }
0421 
0422 EXPORT_SYMBOL(dibx000_reset_i2c_master);
0423 
0424 static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
0425                 struct i2c_algorithm *algo, const char *name,
0426                 struct dibx000_i2c_master *mst)
0427 {
0428     strscpy(i2c_adap->name, name, sizeof(i2c_adap->name));
0429     i2c_adap->algo = algo;
0430     i2c_adap->algo_data = NULL;
0431     i2c_set_adapdata(i2c_adap, mst);
0432     if (i2c_add_adapter(i2c_adap) < 0)
0433         return -ENODEV;
0434     return 0;
0435 }
0436 
0437 int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
0438                 struct i2c_adapter *i2c_adap, u8 i2c_addr)
0439 {
0440     int ret;
0441 
0442     mutex_init(&mst->i2c_buffer_lock);
0443     if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0444         dprintk("could not acquire lock\n");
0445         return -EINVAL;
0446     }
0447     memset(mst->msg, 0, sizeof(struct i2c_msg));
0448     mst->msg[0].addr = i2c_addr >> 1;
0449     mst->msg[0].flags = 0;
0450     mst->msg[0].buf = mst->i2c_write_buffer;
0451     mst->msg[0].len = 4;
0452 
0453     mst->device_rev = device_rev;
0454     mst->i2c_adap = i2c_adap;
0455     mst->i2c_addr = i2c_addr >> 1;
0456 
0457     if (device_rev == DIB7000P || device_rev == DIB8000)
0458         mst->base_reg = 1024;
0459     else
0460         mst->base_reg = 768;
0461 
0462     mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
0463     if (i2c_adapter_init
0464             (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
0465              "DiBX000 tuner I2C bus", mst) != 0)
0466         pr_err("could not initialize the tuner i2c_adapter\n");
0467 
0468     mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
0469     if (i2c_adapter_init
0470             (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
0471              "DiBX000 master GPIO12 I2C bus", mst) != 0)
0472         pr_err("could not initialize the master i2c_adapter\n");
0473 
0474     mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
0475     if (i2c_adapter_init
0476             (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
0477              "DiBX000 master GPIO34 I2C bus", mst) != 0)
0478         pr_err("could not initialize the master i2c_adapter\n");
0479 
0480     mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
0481     if (i2c_adapter_init
0482             (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
0483              "DiBX000 master GPIO67 I2C bus", mst) != 0)
0484         pr_err("could not initialize the master i2c_adapter\n");
0485 
0486     /* initialize the i2c-master by closing the gate */
0487     dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
0488 
0489     ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
0490     mutex_unlock(&mst->i2c_buffer_lock);
0491 
0492     return ret;
0493 }
0494 
0495 EXPORT_SYMBOL(dibx000_init_i2c_master);
0496 
0497 void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
0498 {
0499     i2c_del_adapter(&mst->gated_tuner_i2c_adap);
0500     i2c_del_adapter(&mst->master_i2c_adap_gpio12);
0501     i2c_del_adapter(&mst->master_i2c_adap_gpio34);
0502     i2c_del_adapter(&mst->master_i2c_adap_gpio67);
0503 }
0504 EXPORT_SYMBOL(dibx000_exit_i2c_master);
0505 
0506 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
0507 MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
0508 MODULE_LICENSE("GPL");