Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | // SPDX-License-Identifier: GPL-2.0-or-later /* Mantis VP-2033 driver Copyright (C) Manu Abraham (abraham.manu@gmail.com) */ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <media/dmxdev.h> #include <media/dvbdev.h> #include <media/dvb_demux.h> #include <media/dvb_frontend.h> #include <media/dvb_net.h> #include "tda1002x.h" #include "mantis_common.h" #include "mantis_ioc.h" #include "mantis_dvb.h" #include "mantis_vp2033.h" #define MANTIS_MODEL_NAME "VP-2033" #define MANTIS_DEV_TYPE "DVB-C" static struct tda1002x_config vp2033_tda1002x_cu1216_config = { .demod_address = 0x18 >> 1, .invert = 1, }; static struct tda10023_config vp2033_tda10023_cu1216_config = { .demod_address = 0x18 >> 1, .invert = 1, }; static u8 read_pwm(struct mantis_pci *mantis) { struct i2c_adapter *adapter = &mantis->adapter; u8 b = 0xff; u8 pwm; struct i2c_msg msg[] = { {.addr = 0x50, .flags = 0, .buf = &b, .len = 1}, {.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} }; if ((i2c_transfer(adapter, msg, 2) != 2) || (pwm == 0xff)) pwm = 0x48; return pwm; } static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe) { struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mantis_pci *mantis = fe->dvb->priv; struct i2c_adapter *adapter = &mantis->adapter; u8 buf[6]; struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)}; int i; #define CU1216_IF 36125000 #define TUNER_MUL 62500 u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = 0xce; buf[3] = (p->frequency < 150000000 ? 0x01 : p->frequency < 445000000 ? 0x02 : 0x04); buf[4] = 0xde; buf[5] = 0x20; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(adapter, &msg, 1) != 1) return -EIO; /* wait for the pll lock */ msg.flags = I2C_M_RD; msg.len = 1; for (i = 0; i < 20; i++) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40)) break; msleep(10); } /* switch the charge pump to the lower current */ msg.flags = 0; msg.len = 2; msg.buf = &buf[2]; buf[2] &= ~0x40; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(adapter, &msg, 1) != 1) return -EIO; return 0; } static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe) { struct i2c_adapter *adapter = &mantis->adapter; int err = 0; err = mantis_frontend_power(mantis, POWER_ON); if (err == 0) { mantis_frontend_soft_reset(mantis); msleep(250); dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)"); fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config, adapter, read_pwm(mantis)); if (fe) { dprintk(MANTIS_ERROR, 1, "found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x", vp2033_tda1002x_cu1216_config.demod_address); } else { fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config, adapter, read_pwm(mantis)); if (fe) { dprintk(MANTIS_ERROR, 1, "found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x", vp2033_tda1002x_cu1216_config.demod_address); } } if (fe) { fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set; dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success"); } else { return -1; } } else { dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>", adapter->name, err); return -EIO; } mantis->fe = fe; dprintk(MANTIS_DEBUG, 1, "Done!"); return 0; } struct mantis_hwconfig vp2033_config = { .model_name = MANTIS_MODEL_NAME, .dev_type = MANTIS_DEV_TYPE, .ts_size = MANTIS_TS_204, .baud_rate = MANTIS_BAUD_9600, .parity = MANTIS_PARITY_NONE, .bytes = 0, .frontend_init = vp2033_frontend_init, .power = GPIF_A12, .reset = GPIF_A13, }; |