Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] ttusb2: add support for the dvb-t part of CT-3650 v3

Signed-off-by: Jose Alberto Reguero <jareguero@telefonica.net>
Reviewed-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Jose Alberto Reguero and committed by
Mauro Carvalho Chehab
c9f88aa9 84b27148

+110 -25
+77 -13
drivers/media/dvb/dvb-usb/ttusb2.c
··· 30 30 #include "tda826x.h" 31 31 #include "tda10086.h" 32 32 #include "tda1002x.h" 33 + #include "tda10048.h" 33 34 #include "tda827x.h" 34 35 #include "lnbp21.h" 35 36 ··· 83 82 { 84 83 struct dvb_usb_device *d = i2c_get_adapdata(adap); 85 84 static u8 obuf[60], ibuf[60]; 86 - int i,read; 85 + int i, write_read, read; 87 86 88 87 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 89 88 return -EAGAIN; ··· 92 91 warn("more than 2 i2c messages at a time is not handled yet. TODO."); 93 92 94 93 for (i = 0; i < num; i++) { 95 - read = i+1 < num && (msg[i+1].flags & I2C_M_RD); 94 + write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD); 95 + read = msg[i].flags & I2C_M_RD; 96 96 97 - obuf[0] = (msg[i].addr << 1) | read; 98 - obuf[1] = msg[i].len; 97 + obuf[0] = (msg[i].addr << 1) | (write_read | read); 98 + if (read) 99 + obuf[1] = 0; 100 + else 101 + obuf[1] = msg[i].len; 99 102 100 103 /* read request */ 101 - if (read) 104 + if (write_read) 102 105 obuf[2] = msg[i+1].len; 106 + else if (read) 107 + obuf[2] = msg[i].len; 103 108 else 104 109 obuf[2] = 0; 105 110 106 - memcpy(&obuf[3],msg[i].buf,msg[i].len); 111 + memcpy(&obuf[3], msg[i].buf, msg[i].len); 107 112 108 113 if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { 109 114 err("i2c transfer failed."); 110 115 break; 111 116 } 112 117 113 - if (read) { 114 - memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len); 118 + if (write_read) { 119 + memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len); 115 120 i++; 116 - } 121 + } else if (read) 122 + memcpy(msg[i].buf, &ibuf[3], msg[i].len); 117 123 } 118 124 119 125 mutex_unlock(&d->i2c_mutex); ··· 198 190 .deltaf = 0xa511, 199 191 }; 200 192 193 + static struct tda10048_config tda10048_config = { 194 + .demod_address = 0x10 >> 1, 195 + .output_mode = TDA10048_PARALLEL_OUTPUT, 196 + .inversion = TDA10048_INVERSION_ON, 197 + .dtv6_if_freq_khz = TDA10048_IF_4000, 198 + .dtv7_if_freq_khz = TDA10048_IF_4500, 199 + .dtv8_if_freq_khz = TDA10048_IF_5000, 200 + .clk_freq_khz = TDA10048_CLK_16000, 201 + .no_firmware = 1, 202 + .set_pll = true , 203 + .pll_m = 5, 204 + .pll_n = 3, 205 + .pll_p = 0, 206 + }; 207 + 208 + static struct tda827x_config tda827x_config = { 209 + .config = 0, 210 + }; 211 + 201 212 static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) 202 213 { 203 214 if (usb_set_interface(adap->dev->udev,0,3) < 0) ··· 230 203 return 0; 231 204 } 232 205 206 + static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 207 + { 208 + struct dvb_usb_adapter *adap = fe->dvb->priv; 209 + 210 + return adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], enable); 211 + } 212 + 233 213 static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap) 234 214 { 235 215 if (usb_set_interface(adap->dev->udev, 0, 3) < 0) 236 216 err("set interface to alts=3 failed"); 237 - if ((adap->fe[0] = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) { 238 - deb_info("TDA10023 attach failed\n"); 239 - return -ENODEV; 217 + 218 + if (adap->fe[0] == NULL) { 219 + /* FE 0 DVB-C */ 220 + adap->fe[0] = dvb_attach(tda10023_attach, 221 + &tda10023_config, &adap->dev->i2c_adap, 0x48); 222 + 223 + if (adap->fe[0] == NULL) { 224 + deb_info("TDA10023 attach failed\n"); 225 + return -ENODEV; 226 + } 227 + } else { 228 + adap->fe[1] = dvb_attach(tda10048_attach, 229 + &tda10048_config, &adap->dev->i2c_adap); 230 + 231 + if (adap->fe[1] == NULL) { 232 + deb_info("TDA10048 attach failed\n"); 233 + return -ENODEV; 234 + } 235 + 236 + /* tuner is behind TDA10023 I2C-gate */ 237 + adap->fe[1]->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl; 238 + 240 239 } 240 + 241 241 return 0; 242 242 } 243 243 244 244 static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) 245 245 { 246 - if (dvb_attach(tda827x_attach, adap->fe[0], 0x61, &adap->dev->i2c_adap, NULL) == NULL) { 246 + struct dvb_frontend *fe; 247 + 248 + /* MFE: select correct FE to attach tuner since that's called twice */ 249 + if (adap->fe[1] == NULL) 250 + fe = adap->fe[0]; 251 + else 252 + fe = adap->fe[1]; 253 + 254 + /* attach tuner */ 255 + if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) { 247 256 printk(KERN_ERR "%s: No tda827x found!\n", __func__); 248 257 return -ENODEV; 249 258 } ··· 448 385 { 449 386 .streaming_ctrl = NULL, 450 387 388 + .num_frontends = 2, 451 389 .frontend_attach = ttusb2_frontend_tda10023_attach, 452 390 .tuner_attach = ttusb2_tuner_tda827x_attach, 453 391
+25 -12
drivers/media/dvb/frontends/tda10048.c
··· 206 206 static struct pll_tab { 207 207 u32 clk_freq_khz; 208 208 u32 if_freq_khz; 209 - u8 m, n, p; 210 209 } pll_tab[] = { 211 - { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 }, 212 - { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 }, 213 - { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 }, 214 - { TDA10048_CLK_16000, TDA10048_IF_3800, 10, 3, 0 }, 215 - { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, 216 - { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, 217 - { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, 210 + { TDA10048_CLK_4000, TDA10048_IF_36130 }, 211 + { TDA10048_CLK_16000, TDA10048_IF_3300 }, 212 + { TDA10048_CLK_16000, TDA10048_IF_3500 }, 213 + { TDA10048_CLK_16000, TDA10048_IF_3800 }, 214 + { TDA10048_CLK_16000, TDA10048_IF_4000 }, 215 + { TDA10048_CLK_16000, TDA10048_IF_4300 }, 216 + { TDA10048_CLK_16000, TDA10048_IF_4500 }, 217 + { TDA10048_CLK_16000, TDA10048_IF_5000 }, 218 + { TDA10048_CLK_16000, TDA10048_IF_36130 }, 218 219 }; 219 220 220 221 static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) ··· 461 460 462 461 state->freq_if_hz = pll_tab[i].if_freq_khz * 1000; 463 462 state->xtal_hz = pll_tab[i].clk_freq_khz * 1000; 464 - state->pll_mfactor = pll_tab[i].m; 465 - state->pll_nfactor = pll_tab[i].n; 466 - state->pll_pfactor = pll_tab[i].p; 467 463 break; 468 464 } 469 465 } ··· 778 780 int ret = 0, i; 779 781 780 782 dprintk(1, "%s()\n", __func__); 783 + 784 + /* PLL */ 785 + init_tab[4].data = (u8)(state->pll_mfactor); 786 + init_tab[5].data = (u8)(state->pll_nfactor) | 0x40; 781 787 782 788 /* Apply register defaults */ 783 789 for (i = 0; i < ARRAY_SIZE(init_tab); i++) ··· 1125 1123 /* setup the state and clone the config */ 1126 1124 memcpy(&state->config, config, sizeof(*config)); 1127 1125 state->i2c = i2c; 1128 - state->fwloaded = 0; 1126 + state->fwloaded = config->no_firmware; 1129 1127 state->bandwidth = BANDWIDTH_8_MHZ; 1130 1128 1131 1129 /* check if the demod is present */ ··· 1136 1134 memcpy(&state->frontend.ops, &tda10048_ops, 1137 1135 sizeof(struct dvb_frontend_ops)); 1138 1136 state->frontend.demodulator_priv = state; 1137 + 1138 + /* set pll */ 1139 + if (config->set_pll) { 1140 + state->pll_mfactor = config->pll_m; 1141 + state->pll_nfactor = config->pll_n; 1142 + state->pll_pfactor = config->pll_p; 1143 + } else { 1144 + state->pll_mfactor = 10; 1145 + state->pll_nfactor = 3; 1146 + state->pll_pfactor = 0; 1147 + } 1139 1148 1140 1149 /* Establish any defaults the the user didn't pass */ 1141 1150 tda10048_establish_defaults(&state->frontend);
+8
drivers/media/dvb/frontends/tda10048.h
··· 51 51 #define TDA10048_IF_4300 4300 52 52 #define TDA10048_IF_4500 4500 53 53 #define TDA10048_IF_4750 4750 54 + #define TDA10048_IF_5000 5000 54 55 #define TDA10048_IF_36130 36130 55 56 u16 dtv6_if_freq_khz; 56 57 u16 dtv7_if_freq_khz; ··· 63 62 64 63 /* Disable I2C gate access */ 65 64 u8 disable_gate_access; 65 + 66 + bool no_firmware; 67 + 68 + bool set_pll; 69 + u8 pll_m; 70 + u8 pll_p; 71 + u8 pll_n; 66 72 }; 67 73 68 74 #if defined(CONFIG_DVB_TDA10048) || \