0001
0002
0003
0004
0005
0006
0007
0008 #include "tda18212.h"
0009 #include <linux/regmap.h>
0010
0011 struct tda18212_dev {
0012 struct tda18212_config cfg;
0013 struct i2c_client *client;
0014 struct regmap *regmap;
0015
0016 u32 if_frequency;
0017 };
0018
0019 static int tda18212_set_params(struct dvb_frontend *fe)
0020 {
0021 struct tda18212_dev *dev = fe->tuner_priv;
0022 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0023 int ret, i;
0024 u32 if_khz;
0025 u8 buf[9];
0026 #define DVBT_6 0
0027 #define DVBT_7 1
0028 #define DVBT_8 2
0029 #define DVBT2_6 3
0030 #define DVBT2_7 4
0031 #define DVBT2_8 5
0032 #define DVBC_6 6
0033 #define DVBC_8 7
0034 #define ATSC_VSB 8
0035 #define ATSC_QAM 9
0036 static const u8 bw_params[][3] = {
0037
0038 [DVBT_6] = { 0xb3, 0x20, 0x03 },
0039 [DVBT_7] = { 0xb3, 0x31, 0x01 },
0040 [DVBT_8] = { 0xb3, 0x22, 0x01 },
0041 [DVBT2_6] = { 0xbc, 0x20, 0x03 },
0042 [DVBT2_7] = { 0xbc, 0x72, 0x03 },
0043 [DVBT2_8] = { 0xbc, 0x22, 0x01 },
0044 [DVBC_6] = { 0x92, 0x50, 0x03 },
0045 [DVBC_8] = { 0x92, 0x53, 0x03 },
0046 [ATSC_VSB] = { 0x7d, 0x20, 0x63 },
0047 [ATSC_QAM] = { 0x7d, 0x20, 0x63 },
0048 };
0049
0050 dev_dbg(&dev->client->dev,
0051 "delivery_system=%d frequency=%d bandwidth_hz=%d\n",
0052 c->delivery_system, c->frequency,
0053 c->bandwidth_hz);
0054
0055 if (fe->ops.i2c_gate_ctrl)
0056 fe->ops.i2c_gate_ctrl(fe, 1);
0057
0058 switch (c->delivery_system) {
0059 case SYS_ATSC:
0060 if_khz = dev->cfg.if_atsc_vsb;
0061 i = ATSC_VSB;
0062 break;
0063 case SYS_DVBC_ANNEX_B:
0064 if_khz = dev->cfg.if_atsc_qam;
0065 i = ATSC_QAM;
0066 break;
0067 case SYS_DVBT:
0068 switch (c->bandwidth_hz) {
0069 case 6000000:
0070 if_khz = dev->cfg.if_dvbt_6;
0071 i = DVBT_6;
0072 break;
0073 case 7000000:
0074 if_khz = dev->cfg.if_dvbt_7;
0075 i = DVBT_7;
0076 break;
0077 case 8000000:
0078 if_khz = dev->cfg.if_dvbt_8;
0079 i = DVBT_8;
0080 break;
0081 default:
0082 ret = -EINVAL;
0083 goto error;
0084 }
0085 break;
0086 case SYS_DVBT2:
0087 switch (c->bandwidth_hz) {
0088 case 6000000:
0089 if_khz = dev->cfg.if_dvbt2_6;
0090 i = DVBT2_6;
0091 break;
0092 case 7000000:
0093 if_khz = dev->cfg.if_dvbt2_7;
0094 i = DVBT2_7;
0095 break;
0096 case 8000000:
0097 if_khz = dev->cfg.if_dvbt2_8;
0098 i = DVBT2_8;
0099 break;
0100 default:
0101 ret = -EINVAL;
0102 goto error;
0103 }
0104 break;
0105 case SYS_DVBC_ANNEX_A:
0106 case SYS_DVBC_ANNEX_C:
0107 if_khz = dev->cfg.if_dvbc;
0108 i = DVBC_8;
0109 break;
0110 default:
0111 ret = -EINVAL;
0112 goto error;
0113 }
0114
0115 ret = regmap_write(dev->regmap, 0x23, bw_params[i][2]);
0116 if (ret)
0117 goto error;
0118
0119 ret = regmap_write(dev->regmap, 0x06, 0x00);
0120 if (ret)
0121 goto error;
0122
0123 ret = regmap_write(dev->regmap, 0x0f, bw_params[i][0]);
0124 if (ret)
0125 goto error;
0126
0127 buf[0] = 0x02;
0128 buf[1] = bw_params[i][1];
0129 buf[2] = 0x03;
0130 buf[3] = DIV_ROUND_CLOSEST(if_khz, 50);
0131 buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
0132 buf[5] = ((c->frequency / 1000) >> 8) & 0xff;
0133 buf[6] = ((c->frequency / 1000) >> 0) & 0xff;
0134 buf[7] = 0xc1;
0135 buf[8] = 0x01;
0136 ret = regmap_bulk_write(dev->regmap, 0x12, buf, sizeof(buf));
0137 if (ret)
0138 goto error;
0139
0140
0141 dev->if_frequency = buf[3] * 50 * 1000;
0142
0143 exit:
0144 if (fe->ops.i2c_gate_ctrl)
0145 fe->ops.i2c_gate_ctrl(fe, 0);
0146
0147 return ret;
0148
0149 error:
0150 dev_dbg(&dev->client->dev, "failed=%d\n", ret);
0151 goto exit;
0152 }
0153
0154 static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0155 {
0156 struct tda18212_dev *dev = fe->tuner_priv;
0157
0158 *frequency = dev->if_frequency;
0159
0160 return 0;
0161 }
0162
0163 static const struct dvb_tuner_ops tda18212_tuner_ops = {
0164 .info = {
0165 .name = "NXP TDA18212",
0166
0167 .frequency_min_hz = 48 * MHz,
0168 .frequency_max_hz = 864 * MHz,
0169 .frequency_step_hz = 1 * kHz,
0170 },
0171
0172 .set_params = tda18212_set_params,
0173 .get_if_frequency = tda18212_get_if_frequency,
0174 };
0175
0176 static int tda18212_probe(struct i2c_client *client,
0177 const struct i2c_device_id *id)
0178 {
0179 struct tda18212_config *cfg = client->dev.platform_data;
0180 struct dvb_frontend *fe = cfg->fe;
0181 struct tda18212_dev *dev;
0182 int ret;
0183 unsigned int chip_id;
0184 char *version;
0185 static const struct regmap_config regmap_config = {
0186 .reg_bits = 8,
0187 .val_bits = 8,
0188 };
0189
0190 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0191 if (dev == NULL) {
0192 ret = -ENOMEM;
0193 dev_err(&client->dev, "kzalloc() failed\n");
0194 goto err;
0195 }
0196
0197 memcpy(&dev->cfg, cfg, sizeof(struct tda18212_config));
0198 dev->client = client;
0199 dev->regmap = devm_regmap_init_i2c(client, ®map_config);
0200 if (IS_ERR(dev->regmap)) {
0201 ret = PTR_ERR(dev->regmap);
0202 goto err;
0203 }
0204
0205
0206 if (fe->ops.i2c_gate_ctrl)
0207 fe->ops.i2c_gate_ctrl(fe, 1);
0208
0209 ret = regmap_read(dev->regmap, 0x00, &chip_id);
0210 dev_dbg(&dev->client->dev, "chip_id=%02x\n", chip_id);
0211
0212 if (fe->ops.i2c_gate_ctrl)
0213 fe->ops.i2c_gate_ctrl(fe, 0);
0214
0215 if (ret)
0216 goto err;
0217
0218 switch (chip_id) {
0219 case 0xc7:
0220 version = "M";
0221 break;
0222 case 0x47:
0223 version = "S";
0224 break;
0225 default:
0226 ret = -ENODEV;
0227 goto err;
0228 }
0229
0230 dev_info(&dev->client->dev,
0231 "NXP TDA18212HN/%s successfully identified\n", version);
0232
0233 fe->tuner_priv = dev;
0234 memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
0235 sizeof(struct dvb_tuner_ops));
0236 i2c_set_clientdata(client, dev);
0237
0238 return 0;
0239 err:
0240 dev_dbg(&client->dev, "failed=%d\n", ret);
0241 kfree(dev);
0242 return ret;
0243 }
0244
0245 static int tda18212_remove(struct i2c_client *client)
0246 {
0247 struct tda18212_dev *dev = i2c_get_clientdata(client);
0248 struct dvb_frontend *fe = dev->cfg.fe;
0249
0250 dev_dbg(&client->dev, "\n");
0251
0252 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
0253 fe->tuner_priv = NULL;
0254 kfree(dev);
0255
0256 return 0;
0257 }
0258
0259 static const struct i2c_device_id tda18212_id[] = {
0260 {"tda18212", 0},
0261 {}
0262 };
0263 MODULE_DEVICE_TABLE(i2c, tda18212_id);
0264
0265 static struct i2c_driver tda18212_driver = {
0266 .driver = {
0267 .name = "tda18212",
0268 },
0269 .probe = tda18212_probe,
0270 .remove = tda18212_remove,
0271 .id_table = tda18212_id,
0272 };
0273
0274 module_i2c_driver(tda18212_driver);
0275
0276 MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
0277 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
0278 MODULE_LICENSE("GPL");